【问题标题】:Bookmark Program using JavaScript使用 JavaScript 的书签程序
【发布时间】:2021-06-16 06:46:30
【问题描述】:
<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
</head>

<body>
    <div class="container">
        <h1 class="heading">Book Search</h1>
        <input placeholder="Type Book name" class="searchBar" id="searchInput" type="search">
        <br>
        <select id="selectDisplayCount" class="options">
            <option selected value="10">10 Books</option>
            <option value="20">20 Books</option>
            <option value="30">30 Books</option>
        </select>
    </div>
    <div id="searchResults">
        <div class="col-12 d-none mt-5" id="spinner">
            <div class="d-flex flex-row justify-content-center">
                <div class="spinner-border" role="status"></div>
            </div>
        </div>
    </div>

</body>

</html>

let searchInputEl = document.getElementById("searchInput");
let spinnerEl = document.getElementById("spinner");
let searchresultsEl = document.getElementById("searchResults")
let selectDisplayCountEl = document.getElementById("selectDisplayCount");
let bookcount = selectDisplayCountEl.value;

let formData = {
    count: "10 Books",
}

function createAndAppendSearchResult(result) {
    let {
        title,
        imageLink,
        author
    } = result;
    let resultItemEl = document.createElement("div");
    resultItemEl.classList.add("country-card", "col-6", "mr-auto", "ml-auto", "d-flex", "flex-column")
    searchresultsEl.appendChild(resultItemEl);

    let imageEl = document.createElement("img");
    imageEl.classList.add("image", "mt-auto", "mb-auto")
    imageEl.src = imageLink;
    resultItemEl.appendChild(imageEl);

    let authorEl = document.createElement("p");
    authorEl.classList.add("author-name")
    authorEl.textContent = author;
    resultItemEl.appendChild(authorEl);
}

function displaySearchResults(searchresult) {
    for (let result of searchresult) {
        let titleName = result.title
        if (titleName.includes(searchInputEl.value)) {
            createAndAppendSearchResult(result);
        } else {
            searchInputEl.textontent = "No reuslts found";
        }
    }
}

function searchBook(event) {
    if (event.key === "Enter") {
        let url = "https://apis.ccbp.in/book-store?title=kalam&maxResults=30" + searchInput;
        let options = {
            method: "GET"
        }
        spinnerEl.classList.remove("d-none");
        searchresultsEl.classList.add("d-none");
        fetch(url, options)
            .then(function(response) {
                return response.json();
            })
            .then(function(jsonData) {
                searchresultsEl.classList.remove("d-none");
                spinnerEl.classList.add("d-none");
                console.log(jsonData)
                let {
                    search_results
                } = jsonData;
                console.log(JSON.stringify(jsonData))
                displaySearchResults(search_results);
            })
    }
}


selectDisplayCountEl.addEventListener("change", function(event) {
    formData.count = event.target.value;
    console.log(formData.count)
});
searchInputEl.addEventListener("keydown", searchBook);

我遇到的错误

当在 ID 为 searchInput 的 HTML 输入元素中输入值时,在 ID 为 selectDisplayCount 的 HTML 选择元素中选择了 x 个书籍选项,应发出带有有效 url 参数 title 和 maxResults 的 HTTP GET 请求

当在 ID 为 searchInput 的 HTML 输入元素中输入值时,在 ID 为 selectDisplayCount 的 HTML 选择元素中选择了 x 个书籍选项,应发出 HTTP GET 请求以获取并显示 x 个书籍项目

它应该如何工作:

https://assets.ccbp.in/frontend/content/dynamic-webapps/book_search_output.gif

let searchInputEl = document.getElementById("searchInput");
let spinnerEl = document.getElementById("spinner");
let searchresultsEl = document.getElementById("searchResults")
let selectDisplayCountEl = document.getElementById("selectDisplayCount");
let bookcount = selectDisplayCountEl.value;

let formData = {
    count: "10 Books",
}

function createAndAppendSearchResult(result) {
    let {
        title,
        imageLink,
        author
    } = result;
    let resultItemEl = document.createElement("div");
    resultItemEl.classList.add("country-card", "col-6", "mr-auto", "ml-auto", "d-flex", "flex-column")
    searchresultsEl.appendChild(resultItemEl);

    let imageEl = document.createElement("img");
    imageEl.classList.add("image", "mt-auto", "mb-auto")
    imageEl.src = imageLink;
    resultItemEl.appendChild(imageEl);

    let authorEl = document.createElement("p");
    authorEl.classList.add("author-name")
    authorEl.textContent = author;
    resultItemEl.appendChild(authorEl);
}

function displaySearchResults(searchresult) {
    for (let result of searchresult) {
        let titleName = result.title
        if (titleName.includes(searchInputEl.value)) {
            createAndAppendSearchResult(result);
        } else {
            searchInputEl.textontent = "No reuslts found";
        }
    }
}

function searchBook(event) {
    if (event.key === "Enter") {
        let url = "https://apis.ccbp.in/book-store?title=kalam&maxResults=30" + searchInput;
        let options = {
            method: "GET"
        }
        spinnerEl.classList.remove("d-none");
        searchresultsEl.classList.add("d-none");
        fetch(url, options)
            .then(function(response) {
                return response.json();
            })
            .then(function(jsonData) {
                searchresultsEl.classList.remove("d-none");
                spinnerEl.classList.add("d-none");
                console.log(jsonData)
                let {
                    search_results
                } = jsonData;
                console.log(JSON.stringify(jsonData))
                displaySearchResults(search_results);
            })
    }
}


selectDisplayCountEl.addEventListener("change", function(event) {
    formData.count = event.target.value;
    console.log(formData.count)
});
searchInputEl.addEventListener("keydown", searchBook);
<link rel='stylesheet' href='//stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css' integrity='sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z' crossorigin='anonymous' />
<script src='//code.jquery.com/jquery-3.5.1.slim.min.js' integrity='sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj' crossorigin='anonymous'></script>
<script src='//cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js' integrity='sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN' crossorigin='anonymous'></script>
<script src='//stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js' integrity='sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV' crossorigin='anonymous'></script>

<div class='container'>
    <h1 class='heading'>Book Search</h1>
    <input placeholder='Type Book name' class='searchBar' id='searchInput' type='search'>
    <br>
    <select id='selectDisplayCount' class='options'>
        <option selected value='10'>10 Books</option>
        <option value='20'>20 Books</option>
        <option value='30'>30 Books</option>
    </select>
</div>
<div id='searchResults'>
    <div class='col-12 d-none mt-5' id='spinner'>
        <div class='d-flex flex-row justify-content-center'>
            <div class='spinner-border' role='status'></div>
        </div>
    </div>
</div>

【问题讨论】:

  • searchInput 方法在哪里定义?还是应该是searchBook
  • 是的,它实际上是 searchBook 我可能打错了
  • 您能否澄清一下您遇到的问题是什么,因为从问题中并不能立即看出这一点。
  • 完成代码后,它应该像这样工作:(assets.ccbp.in/frd/content/dynamic-webapps/…)。但是在我的程序中,当我点击提交时,它没有指向 URL,也没有给出我希望的结果。

标签: javascript html input hyperlink


【解决方案1】:

根据动画 GIF,select 菜单也应该触发对 3rd 方 api 的 AJAX 请求,但是根据您的代码,它只是更新全局变量formData。由于selectkeydown/enter 都将触发相同的操作,因此可以使用单个事件处理程序。通过对上述内容和一些新功能进行一些重新编写,可以简化代码以完成您正在尝试(我认为)做的事情。

以下代码 sn-p 省略了原始代码中使用的各种外部脚本和样式表,但用于说明结果。

document.addEventListener('DOMContentLoaded',()=>{      
  let oRes=document.getElementById('searchResults');
  let oText=document.getElementById('searchInput');
  let oSel=document.getElementById('selectDisplayCount');
  let oSpin=document.getElementById('spinner');

  const baseurl='https://apis.ccbp.in/book-store';

  // utility to ease construction of full urls in modern browsers
  const buildurl=function( endpoint, params ){
    let url=new URL( endpoint );
      url.search = new URLSearchParams( params ).toString();
    return url;
  };
  
  // utility method to create new DOM elements
  // where t=node type, a=attributes & p=parent to append to.
  const create=function(t,a,p){
    let el = ( typeof( t )=='undefined' || t==null ) ? document.createElement( 'div' ) : document.createElement( t );
    let _arr=['innerHTML','innerText','html','text'];
    for( let x in a ) if( a.hasOwnProperty( x ) && !~_arr.indexOf( x ) ) el.setAttribute( x, a[ x ] );
    if( a.hasOwnProperty('innerHTML') || a.hasOwnProperty('html') ) el.innerHTML=a.innerHTML || a.html;
    if( a.hasOwnProperty('innerText') || a.hasOwnProperty('text') ) el.innerText=a.innerText || a.text;
    if( p!=null ) typeof( p )=='object' ? p.appendChild( el ) : document.getElementById( p ).appendChild( el );
    return el;
  };


  // The callback method to generate output HTML
  const callback=(json)=>{
    toggleclasses(false);

    let data=json.search_results;
    oRes.innerHTML='';

    Object.keys( data ).forEach( k => {
      let obj=data[ k ];

      let div=create(null,{'class':'country-card col-6 mr-auto ml-auto d-flex flex-column'},oRes);
      create('h1',{text:obj.title},div);
      create('img',{src:obj.imageLink,'class':'image mt-auto mb-auto'},div);
      create('p',{text:obj.author,'class':'author-name'},div);
    });             
  };


  // helper to switch classes as per original
  const toggleclasses=(b)=>{
    switch(b){
      case true:
        oSpin.classList.remove('d-none');
        oRes.classList.add('d-none');                       
      break;
      case false:
        oSpin.classList.add('d-none');
        oRes.classList.remove('d-none');
      break;
    }
  };


  // single event handler to send AJAX request
  const requesthandler=(e)=>{
    if( e.key === 'Enter' || e.type=='change' ) {
      toggleclasses(true);

      if( oText.value=='')return;

      let args={
        title:oText.value,
        maxResults:oSel.value
      };
      fetch( buildurl( baseurl, args ) )
        .then( r=>r.json() )
        .then( json=>callback( json ) )
    }
  };




  oSel.addEventListener('change',requesthandler);
  oText.addEventListener('keydown',requesthandler);
});
<div class='container'>
  <h1 class='heading'>Book Search</h1>
  <input placeholder='Type Book name' class='searchBar' id='searchInput' type='search' />

  <br />

  <select id='selectDisplayCount' class='options'>
  <option value='1'>1 Book
  <option value='5'>5 Books
    <option selected value='10'>10 Books
    <option value='20'>20 Books
    <option value='30'>30 Books
  <option value='50'>50 Books
  <option value='100'>100 Books
  </select>
</div>

<div id='searchResults'>
  <div class='col-12 d-none mt-5' id='spinner'>
    <div class='d-flex flex-row justify-content-center'>
      <div class='spinner-border' role='status'></div>
    </div>
  </div>
</div>

【讨论】:

  • 谢谢。我很感激。
  • 但我不知道一半。可以简单一点吗?这样您就可以添加到已经存在的代码而不是完全不同的代码中,以便我更好地理解。我仍然在学习方面。希望不要问太多。
猜你喜欢
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 2014-08-26
相关资源
最近更新 更多