Как я могу заставить работать функции поиска при вводе поисковых запросов в поле ввода?

#javascript #html #forms #api

Вопрос:

Я создаю приложение в стиле новостей, которое использует newsapi. Я хочу спросить, как мне заставить работать функции поиска, как заставить поле ввода HTML отображать результаты того, что вы вводите. Я несколько раз пытался заставить его работать, но не могу. Любые предложения приветствуются.

HTML

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <title>News App</title>

</head>
<body>
<header>

    <h1 class="heading">News</h1>

    <form class="searchform" autocomplete="off">
        <input class="searchBox" name="search" type="text" >
        <button type="submit">Submit</button>
    </form>
    <li class="newsList"></li>
    <script src="js/main.js"></script>
</header>
</body>
 

язык JavaScript

 const newsList = document.querySelector(".newsList")
const newsImage = document.querySelector(".newsList")
const form = document.querySelector("form.search")
newsImage.innerHTML = ''
newsList.innerHTML= ''


const url = 'https://newsapi.org/v2/everything?'  
          'q=${search}amp;'  
          'from=2021-06-02amp;'  
          'sortBy=popularityamp;'  
          'apiKey=****************';


let req = new Request(url);
fetch(req)
    .then(function(response) {
        return response.json()
       }).then((data)=>{
           console.log(data)
           data.articles.map(article => {
               let li = document.createElement('li')
               let a = document.createElement('a')
               let image = document.createElement('span') 
               image.innerHTML = `<img src="${article.urlToImage}" >`
               a.setAttribute('href', article.url)
               a.setAttribute('target','_blank' )
               a.textContent = `${article.title}`
               li.appendChild(a)
               newsList.appendChild(li)
               newsImage.appendChild(image)

           });
       })

       function handleSubmit(e){
       e.preventDefault()
       console.log(e.target)
       }

       form.addEventListener('submit', handleSubmit)
 

Ответ №1:

Итак, у меня нет ключа API к API новостей, который вы используете, но вместо этого я использовал бесплатный API Рика и Морти, чтобы ответить на ваш вопрос.

Мне пришлось внести некоторые изменения в ваш код, чтобы заставить его работать с моим API, но я добавил кучу комментариев в фрагмент кода, чтобы, надеюсь, понять, почему я внес изменения, а также как вы можете изменить его обратно для работы с вашим новостным API. Удачи!

 const characters = document.querySelector(".characters");
const searchInput = document.querySelector("#search");
characters.innerHTML = "";

// We also changed this here to include the actual act of fetching the data - you would instead do your news fetch here.
function handleClick(e) {
  let url = "https://rickandmortyapi.com/api/character/";

  // This here maps a HTMLCollection into a JavaScript array and then removes previous children if they exist,
  // this is to clear the list items prior to a new search.
  if (characters.children.length > 0)
    Array.from(characters.children).forEach((child) => child.remove());

  // If we provide a search input include it in the URL - note the only search we can do here is for pages so the input is now a number.
  // This is where you would instead change your news URL and append the "searchInput.value" into the "search section" like so:
  //
  //   const url =
  //     "https://newsapi.org/v2/everything?"  
  //     `q=${searchInput.value}amp;`  
  //     "from=2021-06-02amp;"  
  //     "sortBy=popularityamp;"  
  //     "apiKey=****************";
  //
  // Note that in order to use a variable you need backticks as your quote delimeter. See like `${variable}` instead of '' or "".

  if (searchInput.value)
    url =
      "https://rickandmortyapi.com/api/character/"  
      `?page=${searchInput.value}`;

  let req = new Request(url);
  fetch(req)
    .then(function (response) {
      return response.json();
    })
    .then((data) => {
      console.log(data);
      // I removed your image mapping here because I had no image from this free Rick and Morty API but I hope you get the idea.
      data.results.map((character) => {
        let li = document.createElement("li");
        let a = document.createElement("a");
        a.setAttribute(
          "href",
          "https://rickandmortyapi.com/api/character"   `/${character.id}`
        );
        a.setAttribute("target", "_blank");
        a.textContent = `${character.name}`;
        li.appendChild(a);
        characters.appendChild(li);
      });
    });
} 
 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- I removed this because I had no css file -->
    <!-- <link rel="stylesheet" href="css/style.css" /> -->
    <title>Test App</title>
  </head>
  <body>
    <header>
      <h1 class="heading">Test</h1>
      <form class="searchform" autocomplete="off">
        <!-- <input id="search" class="searchBox" name="search" type="text" /> -->
        <!-- Because my search in the free API could only handle numbers I changed the type here -->
        <!-- You will want to change that back to the above commented out text field -->
        <input id="search" class="searchBox" name="search" type="number" />
        <!-- Instead of using prevent default I changed the action here to be the onclick of the button -->
        <!-- That fires off our "handleClick()" method that lives in our main.js file -->
        <button type="button" onclick="handleClick()">Submit</button>
      </form>
      <div class="characters"></div>
      <script src="main.js"></script>
    </header>
  </body>
</html>