автор Сара Около

В современной динамической сфере веб-разработки реализация мощной функции поиска является ключевой функцией, которая может значительно улучшить взаимодействие с пользователем и упростить навигацию по большим наборам данных. Если вы хотите добавить возможности живого поиска на свой веб-сайт или веб-приложение, вы попали в нужное место. В этой всеобъемлющей статье будут рассмотрены все тонкости реализации функции поиска в реальном времени с использованием JavaScript.

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

Чтобы эффективно следовать этому руководству, рекомендуется иметь четкое представление об основах HTML, CSS и JavaScript. Знакомство с манипулированием DOM и обработкой событий будет полезно, когда мы углубимся в детали реализации. Тем не менее, даже если вы относительно новичок в JavaScript или веб-разработке, руководство построено таким образом, чтобы предоставить четкие объяснения и пошаговые инструкции, что делает его доступным для учащихся с разным уровнем навыков.

Теперь, чтобы лучше понять важность и использование этой функциональности, мы собираемся создать очень простой проект в качестве примера; более конкретно, приложение для просмотра фильмов, как показано ниже:

Ознакомиться с живой реализацией можно здесь.

В этом проекте мы будем использовать функцию поиска в реальном времени для поиска по списку фильмов из базы данных фильмов. Я знаю, что вы взволнованы, чтобы погрузиться прямо сейчас; мы добираемся туда. Но сначала давайте узнаем немного больше о том, что такое функция живого поиска и ее важность.

Важность функции живого поиска

Функциональность поиска в реальном времени стала жизненно важной в современном цифровом ландшафте, удовлетворяя потребность в эффективном поиске информации и улучшая общее взаимодействие с пользователем. Включив обновление поиска в реальном времени по мере ввода пользователем, поиск в реальном времени обеспечивает немедленную обратную связь и облегчает быстрый доступ к соответствующей информации. Эта динамическая и интерактивная функция поиска дает множество преимуществ пользователям и владельцам веб-сайтов.

  1. Улучшенный пользовательский интерфейс. Интерактивный поиск значительно повышает удобство работы пользователей, обеспечивая простой и интуитивно понятный процесс поиска. Когда пользователи начинают вводить свой запрос, результаты поиска обновляются в режиме реального времени, предлагая мгновенную обратную связь и устраняя необходимость в ручной отправке или перезагрузке страницы. Этот интерактивный характер экономит пользователям драгоценное время и усилия, что приводит к более эффективному и приятному поиску.
  2. Быстрый поиск информации. Благодаря живому поиску пользователи могут быстро находить нужную информацию, не переходя на несколько страниц и не ожидая загрузки результатов поиска. По мере ввода результаты поиска мгновенно сужаются, отображая релевантные предложения и избавляя от необходимости вводить полный поисковый запрос. Эта скорость и отзывчивость позволяют пользователям находить то, что они ищут, за гораздо меньшее время, чем при использовании традиционных методов поиска.
  3. Повышение вовлеченности и конверсий. Бесшовный и отзывчивый характер живого поиска побуждает пользователей более активно взаимодействовать с веб-сайтом или веб-приложением. Предоставление мгновенной обратной связи и актуальных предложений поддерживает вовлеченность пользователей, сводя к минимуму вероятность отказов или разочарования. Это более активное участие может привести к повышению коэффициента конверсии, поскольку пользователи с большей вероятностью будут продолжать изучать сайт и преобразовывать свои поисковые намерения в действия.
  4. Улучшенная фильтрация и уточнение. Функциональность поиска в реальном времени часто включает в себя дополнительные функции, такие как фильтры, предложения и параметры автозаполнения. Эти функции помогают пользователям уточнить поиск и сузить результаты, позволяя им найти то, что они ищут. Предоставляя эти инструменты, поиск в реальном времени улучшает возможности поиска, а также помогает пользователям находить связанный контент или продукты, которые они, возможно, изначально не рассматривали.
  5. Полезная информация для владельцев веб-сайтов. Функция живого поиска может предоставить ценную информацию о поведении и предпочтениях пользователей. Анализируя поисковые запросы и шаблоны, владельцы веб-сайтов могут лучше понимать, что ищут их пользователи, выявлять популярные тенденции или темы и принимать обоснованные решения относительно создания контента, предложений продуктов или улучшения пользовательского интерфейса. Эти идеи позволяют владельцам веб-сайтов адаптировать свои предложения для лучшего удовлетворения потребностей пользователей, что приводит к повышению удовлетворенности клиентов и росту бизнеса.

Настройка структуры HTML

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

Во-первых, давайте настроим структуру проекта. Для этого проекта нам понадобятся всего три файла, то есть файлы HTML, CSS и JavaScript.

Теперь давайте начнем с настройки HTML-структуры нашего проекта:
Внутри HTML-файла нам сначала нужно включить наш стандартный HTML-шаблон, включая ссылку и скрипт на наши файлы CSS и JS:

<!doctype html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <link rel="stylesheet" href="./live-search.css" />
   <title> </title>
 </head>
 <body>
   <script src="./live-search.js"></script>
 </body>
</html>

Теперь в тег body мы включаем семантические теги header и main. Внутри тега header мы настраиваем раздел заголовка нашего проекта, который в данном случае представляет собой просто имя приложения и значок видео.

<header>
 <ion-icon name="videocam"></ion-icon>
 <h1>Search Movies</h1>
</header>

Прежде чем мы перейдем к тегу main, в конце тега body давайте включим необходимые теги script в другие, чтобы иметь возможность использовать значки:

<script
 type="module"
 src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"
></script>
<script
 nomodule
 src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"
></script>

Иконки вы можете найти на сайте Ionicons.

Теперь внутри тега main мы собираемся включить наш первый тег div, и это будет наш контейнер панели поиска, а внутри него мы поместим наш тег ввода поиска и значок поиска:

<div id="search-container">
 <ion-icon name="search-outline"></ion-icon>
 <input type="search" id="search-bar" placeholder="Search movies..." />
</div>

Затем мы создадим еще один тег div под этим «div». Это будет содержать все результаты данных фильма:

<div id="results-container"></div>

Мы бы оставили его пока пустым, так как его содержимое будет сгенерировано в разделе JavaScript.

Наконец, в тег main мы должны включить тег p. Этот тег предназначен просто для отображения ошибки или пустого ответа пользователю позже.

<p id="movie-unavailable-txt"></p>

Это все для файла 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="./live-search.css" />
   <title>Live Search Functionality</title>
 </head>
 <body>
   <header>
     <ion-icon name="videocam"></ion-icon>
     <h1>Search Movies</h1>
   </header>

   <main>
     <div id="search-container">
       <ion-icon name="search-outline"></ion-icon>
       <input type="search" id="search-bar" placeholder="Search movies..." />
     </div>

     <div id="results-container"></div>

     <p id="movie-unavailable-txt"></p>
   </main>

   <script src="./live-search.js"></script>
   <script
     type="module"
     src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"
   ></script>
   <script
     nomodule
     src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"
   ></script>
 </body>
</html>

Теперь, когда мы завершили реализацию HTML-структуры проекта, давайте добавим на страницу несколько стилей.

Добавление стилей на страницу

В этом разделе мы добавим основные стили к различным частям страницы. Итак, давайте погрузимся прямо в.

Во-первых, давайте добавим несколько общих стилей в общий раздел страницы:

html{
 scroll-behavior: smooth;
 background-color: #111;
 color: whitesmoke;
}

*{
 margin: 0;
 padding: 0;
 box-sizing: border-box;
}

Теперь давайте добавим несколько стилей к нашему разделу заголовка и его содержимому:

header{
 display: flex;
 justify-content: center;
 padding: 25px;
 letter-spacing: 2px;
 position: sticky;
 top: 0%;
 z-index: 2;
 border-bottom: 2px solid ;
 background-color: black;
 text-shadow: 3px 3px 5px #fd1d6b;   
 box-shadow: 10px 10px 20px -10px #fd1d6b; 
}

header > ion-icon{
 color:#fd1d6b;
 font-size: 60px;
 position: absolute;
 left: 5%;
}

Далее мы переходим к стилизации контейнера поиска и его содержимого:

#search-container{
 display: flex;
 justify-content: center;
 padding: 20px;
 margin-bottom: 20px;
 position: sticky;
 top: 100px;
}

#search-bar{
 border: none;
 width: 60%;
 padding: 15px;
 padding-left: 40px;
 border-radius: 15px;
 font-size: 15px;
}

#search-container>ion-icon{
 color: gray;
 position: relative;
 left: 30px;
 top: 13px;
 z-index: 3;
 font-size: 19px;
}

После этого мы приступаем к стилю results-container, в котором будут храниться все фильмы, которые мы будем извлекать из базы данных фильмов позже:

#results-container{
 border-right: 5px solid #fd1d6b;
 border-left: 5px solid #fd1d6b;     
 border-radius: 25px;
 display: flex;
 justify-content: center;
 flex-wrap: wrap;
 width: 90vw;
}

Затем мы добавляем стили к movie-unavailable-txt, устанавливая display на none, потому что мы пока не хотим, чтобы он был виден:

#movie-unavailable-txt{
 text-align: center;
 letter-spacing: 2px;
 display: none;
 margin-top: 15%;
 text-shadow: 3px 3px 5px #fd1d6b;
}

Далее мы добавим некоторые стили к нескольким элементам, которые еще не были объявлены, но мы создадим их с помощью javascript. Это карта фильма, которая будет отображать детали фильма, включая изображение фильма и название:

.movie-cards{
 padding: 25px;
 max-width: 250px;
 border-radius: 15px;
 display: grid;
 place-items: center;
 box-shadow: 1px 1px 20px -1px #fd1d6b ;
 margin: 50px;
}

.title{
 margin: 20px auto;
 text-align: center;
 font-size: 1.2rem;
 text-shadow: 3px 3px 5px #fd1d6b;  
}

.date{
 margin-top: 15px;
 font-size: 0.8rem;
 text-shadow: 3px 3px 5px #fd1d6b;  
}

.movie-image{
 width: 90%;
 max-width: 400px;
 object-fit: contain;
 border-radius: 5px;
}

Теперь, когда мы закончили стилизацию страницы, давайте перейдем к самому интересному и важному разделу — реализации Javascript.

Отправка асинхронных поисковых запросов в API базы данных фильмов.

В этом разделе мы будем делать вызовы API к API базы данных фильмов по нашему выбору, чтобы заполнить нашу страницу различными фильмами. В этом случае я буду использовать бесплатный API фильмов IMDb Top 100 Movies в RapidAPI Hub. На странице API мы выбираем конкретные данные, которые вы хотите использовать, а затем копируем код javascript (fetch), который предоставляется в правой части страницы для этих данных, как показано ниже:

Но сначала, прежде чем вы сможете использовать API, сначала подпишитесь на него (кредитная карта не требуется), чтобы для вас мог быть сгенерирован ключ API. Вы можете сделать это на странице с ценами API.

Двигаясь дальше, мы переходим к нашему пустому файлу javascript и вставляем туда код, который мы скопировали:

const url = "https://imdb-top-100-movies.p.rapidapi.com/";
const options = {
 method: "GET",
 headers: {
   "X-RapidAPI-Key": "YOUR GENERATED API KEY",
   "X-RapidAPI-Host": "imdb-top-100-movies.p.rapidapi.com",
 },
};

try {
 const response = await fetch(url, options);
 const result = await response.text();
 console.log(result);
} catch (error) {
 console.error(error);
}

Теперь, когда мы получили API из базы данных фильмов в наш проект, мы можем использовать его данные. Итак, далее мы собираемся объявить несколько переменных, которые нам понадобятся, и поместить их чуть выше блока try в скопированном коде:

const searchBar = document.getElementById("search-bar");
const resultsContainer = document.getElementById("results-container");
const movieUnavailableTxt = document.getElementById("movie-unavailable-txt");
let movieList;
let searchValue;
let searchedMovies;

Мы подходим к назначению этих переменных, которые мы только что создали, держитесь там.

Далее мы вносим некоторые изменения в блок try из скопированного кода, так как хотим полностью интегрировать его с нашим проектом. Итак, сначала нам нужно создать асинхронную функцию:

const fetchMovies = async () => {
 // try catch block goes in here.
};

Внутри этой функции мы поместим весь блок try catch из скопированного нами кода, чтобы мы могли делать асинхронные вызовы API.

Внутри блока try мы избавимся от строки console.log(result) и изменим переменную result на переменную movieList, которую мы объявили ранее, и изменим response.text() в той же строке на response.json(). Это сделано для того, чтобы данные, которые мы получили от вызова API, были представлены в нужном нам формате JSON. Теперь эта строка должна выглядеть так:

movieList = await response.json();

Теперь, когда мы успешно получили фильм из API и вернули наш набор данных JSON, нам нужно заполнить эти данные на нашей странице. Для этого мы вызовем функцию renderMovies() и зададим в качестве аргумента данные, полученные в результате нашего вызова API. Не волнуйтесь, мы скоро создадим функцию:

renderMovies(movieList);

Теперь давайте создадим функцию renderMovies, которую мы только что вызвали в функции fetchMovies(). Эту функцию мы будем использовать для создания нашего динамического шаблона карточки фильма, для которого мы ранее установили стили в нашем файле CSS и в каждом из элементов. в шаблоне мы собираемся установить их содержимое в соответствии с данными, которые мы получили из API, что позволит нам отображать разные фильмы с одним и тем же шаблоном. Затем мы помещаем карточку фильма внутрь элемента resultsContainer. Каждый раз, когда вызывается функция, нам нужно будет очистить resultsContainer, а также установить moviesUnavailableTxt в display="none", потому что мы хотим, чтобы текст не был виден при рендеринге фильмов на страницу, а также очистить массив moviesReturnedOnSearch перед установка в него новых данных, возвращаемых из поля ввода поиска:

const renderMovies = (movies) => {
 resultsContainer.innerHTML = ""; // Clear the existing movies
 movieUnavailableTxt.style.display = "none"; // Hide the "No movies found" message
 moviesReturnedOnSearch = []; // Clear the movies returned on search array

 movies.forEach((movie) => {
   resultsContainer.innerHTML += `
     <div class="movie-cards">
       <img src="${movie.image}" alt="movie image" class="movie-image" />
       <h2 class="title">${movie.title}</h2>
       <p class="plot">${movie.description}</p>
       <p class="date">${movie.year}</p>
     </div>
   `;

   moviesReturnedOnSearch.push(movie); // Add the movies that are a result to the search input value
 });
};

Воспроизведение сеанса для разработчиков

Раскройте разочарования, выявите ошибки и устраните замедления работы, как никогда раньше, с помощью OpenReplay — набора для воспроизведения сеансов с открытым исходным кодом для разработчиков. Его можно разместить самостоятельно за несколько минут, что даст вам полный контроль над данными ваших клиентов. Проверьте наш репозиторий GitHub и присоединяйтесь к тысячам разработчиков в нашем сообществе.

Удачной отладки! Попробуйте использовать OpenReplay сегодня.

Захват пользовательского ввода и отображение результатов поиска фильмов в реальном времени

Теперь, когда мы загрузили все данные фильмов на нашу страницу, наступает самая интересная часть, где мы реализуем функцию живого поиска, так что, не теряя времени, давайте сразу же погрузимся.

Для захвата пользовательского ввода мы будем использовать прослушиватель событий input и связать его с элементом searchBar. Мы используем этот конкретный прослушиватель событий, потому что он фиксирует каждое действие внутри окна поиска, от набора текста до очистки и вставки, а это именно то, что нам нужно. Итак, давайте продолжим и создадим это:

searchBar.addEventListener("input", (event) => {
 // live functionality code
});

Итак, теперь мы связали прослушиватель событий input с панелью поиска, чтобы прослушивать любой ввод от пользователя. Во втором параметре мы добавили обработчик событий, который представляет собой функцию, которая будет вызываться всякий раз, когда в строке поиска делается один ввод. Теперь внутри этой функции мы создадим код, который обрабатывает поиск в реальном времени.

Первое, что нам нужно сделать внутри функции поиска, это отредактировать входное значение, полученное от пользователя, и установить его в нижний регистр, а также избавиться от всех ненужных пробелов:

searchValue = event.target.value.trim().toLowerCase()

После этого мы приступаем к фильтрации фильма на странице по названию на основе введенных пользователем данных поиска, проверяя, включает ли название фильма, введенное пользователем, какие-либо названия фильмов в данных movieList, а также устанавливая названия фильмов. в нижний регистр, чтобы соответствовать вводу от пользователя:

const filteredMovies = movieList.filter( (movie) => movie.title.toLowerCase().includes(searchValue) );

Затем мы собираемся отображать результаты поиска фильмов в реальном времени, отображая любое название фильма, совпадающее с символами, которые пользователь ввел в строке поиска, вызвав функцию renderMovies() еще раз и установив аргументы в значение переменной filtered Movies. .

renderMovies(filteredMovies);

Вызывая эту функцию, она отображает на странице только те фильмы, названия которых совпадают с любыми символами, которые были введены в строку поиска с использованием шаблона карточки фильма, предоставленного в функции, а также добавляет каждый из совпадающих фильмов в массив moviesReturnedOnSearch, поэтому мы может отслеживать, сколько фильмов соответствует искомому значению для каждого введенного символа. Это было бы полезно при обработке ошибок пустого ответа, с которыми мы сейчас столкнемся.

Обработка пустых ответов или ответов об ошибках

В любом приложении эффективная обработка пустых ответов или ответов с ошибками имеет решающее значение. В этом случае эти сценарии могут возникать, когда поисковый запрос не дает никаких результатов или возникают проблемы с запросом API.

Для обработки ошибок или пустых ответов важно предоставить пользователю четкую обратную связь. Тем не менее, поскольку это довольно легкое приложение, нам не нужно беспокоиться об этом большом количестве ошибок, поскольку мы будем иметь дело только с ошибками, возникающими из-за API. Например, службы API могут быть временно отключены или приложение может просто превысило лимит запросов. Чтобы обработать эту ошибку, нам просто нужно установить display элемента movieUnavailableTxt в block и установить innerHTML для отображения сообщения об ошибке пользователю и поместить его в блок catch функции fetchMovies(). Теперь блок catch выглядит так:

catch (error) {
 movieUnavailableTxt.innerHTML = 'An error occurred while fetching movies. <br /> Please try again later.';
 movieUnavailableTxt.style.display = "block";
 console.error(error);
}

Теперь, когда мы закончили обработку ответа об ошибке, давайте перейдем к обработке пустого ответа. Если фильм, который ищет пользователь, не соответствует ни одному из фильмов на странице, нам придется предупредить пользователя о том, что искомый фильм недоступен. Для этого сначала нам нужно проверить содержимое массива moviesReturnedOnSearch, который мы объявили ранее, и, если длина массива меньше или равна 0, мы затем устанавливаем display элемента movieUnavailableTxt в block и устанавливаем innerHTML к пустому ответному сообщению, которое мы хотим отобразить, как показано ниже:

if (moviesReturnedOnSearch.length <= 0) {
 movieUnavailableTxt.innerHTML = "OOPS! <br/><br/> Movie not available";
 movieUnavailableTxt.style.display = "block"; // Show the "No movies found" message if no movies match the search
}

Затем мы поместим этот блок if непосредственно перед закрывающей скобкой обработчика события searchBar.

Повышение эффективности поиска с помощью кэширования

При реализации функции поиска в реальном времени с помощью API одним из эффективных методов повышения производительности является кэширование. Кэширование включает в себя сохранение ранее извлеченных результатов поиска и их повторное использование при повторном запросе того же поискового запроса. Это может значительно сократить количество вызовов API, что может помочь предотвратить превышение лимита запросов API и в целом повысить скорость отклика функции поиска, а также время загрузки веб-сайта.

Чтобы реализовать кэширование в нашем проекте, во-первых, нам нужно определить, какой элемент необходимо кэшировать, и в этом случае это будет значение переменной movieList, которая представляет собой данные, которые мы получили из нашего запроса API fetch в формате JSON. . Кэшируя этот элемент, мы сможем использовать данные API, не делая ни одного дополнительного запроса fetch даже при перезагрузке страницы. Но для этого проекта мы установим время истечения срока действия наших кэшированных данных в 6 часов, что означает, что страница будет делать запрос API только один раз каждые 6 часов, а не при каждой перезагрузке страницы. Это делается для того, чтобы страница могла сохранять свои данные свежими и актуальными, сводя к минимуму запрос API.

Возвращаясь к нашему коду, сейчас нам нужно сохранить данные JSON в локальном хранилище браузера, но для этого нам нужно сначала преобразовать их в string и установить имя ключа, которое будет использоваться для идентификации данных. в локальном хранилище. Давайте просто установим его на movieData, как показано ниже:

localStorage.setItem("moviedata", JSON.stringify(movieList));

Следующее, что нам нужно сделать, это сохранить текущую дату и время в локальном хранилище:

localStorage.setItem("cacheTimestamp", Date.now());

Это сохраняет текущую дату и время в миллисекундах с именем ключа cacheTimeStamp.

Мы поместим эти две строки кода внутри блока try функции fetchMovies(), прямо под переменной movieList.

Далее, вне функции fetchMovies(), чуть ниже функции renderMovies(), мы собираемся установить срок действия наших кэшированных данных равным 6 часам в миллисекундах:

const expirationDuration = 21600000; // 6 hours in milliseconds

После этого нам нужно вернуть cacheTimestamp, который мы установили в локальном хранилище ранее:

const cacheTimestamp = localStorage.getItem("cacheTimestamp");

Теперь мы проверим, истек ли срок действия кэшированных данных или они недоступны, то есть они еще не сохранены. Если это так, мы сделаем новый запрос fetch к API, вызвав функцию fetchMovies(). С другой стороны, если кешированные данные присутствуют и срок их действия еще не истек, мы будем использовать их для рендеринга фильмов на странице, а не снова делать новый запрос fetch. Мы делаем это, извлекая кэшированные данные фильма и анализируя их обратно в формат JSON для использования, а затем вызывая функцию render с аргументом, установленным на данные, полученные из кэша.

// Check if cache has expired or data is not available
if (
 !cacheTimestamp ||
 Date.now() - parseInt(cacheTimestamp) > expirationDuration
) {
 // Cache expired or data not available, fetch movies again
 fetchMovies();
} else {
 // Use cached movie data
 movieList = JSON.parse(localStorage.getItem("moviedata"));
 renderMovies(movieList);
}

В операторе if !cacheTimestamp проверяет, является ли переменная cacheTimestamp ложной, то есть это либо null, undefined, 0, false, либо пустая строка. Если cacheTimestamp имеет значение false, это означает, что временная метка существующего кэша не сохраняется. Date.now() - parseInt(cacheTimestamp) вычисляет разницу во времени между текущей отметкой времени и проанализированным целочисленным значением cacheTimestamp. Это просто то, что мы говорим: «Значение текущего времени минус значение времени, которое мы ранее сохранили в кеше, больше, чем время истечения, которое мы установили? если да, продолжайте снова получать фильмы из API, а если нет, просто используйте кешированные данные».

И вот оно у вас; именно так мы кэшируем данные для повторного использования, а не делаем запрос fetch при каждом вводе пользователя или каждой перезагрузке страницы. Как видите, это значительно оптимизирует производительность приложения, поскольку предотвращает медленную визуализацию фильмов, которая может возникнуть из-за медленной сети.

Мы закончили реализацию всех функций в нашем маленьком видео-приложении, которое демонстрирует, как работает функция поиска в реальном времени. Ниже приведен общий код javascript для этого приложения:

const url = "https://imdb-top-100-movies.p.rapidapi.com/";
const options = {
 method: "GET",
 headers: {
   "X-RapidAPI-Key": "Your Generated API Key",
   "X-RapidAPI-Host": "imdb-top-100-movies.p.rapidapi.com",
 },
};

const searchBar = document.getElementById("search-bar");
const resultsContainer = document.getElementById("results-container");
const movieUnavailableTxt = document.getElementById("movie-unavailable-txt");
let movieList;
let searchValue;
let moviesReturnedOnSearch;

// Function to fetch movies from the API
const fetchMovies = async () => {
 try {
   const response = await fetch(url, options);
   movieList = await response.json();

   // Storing the Movie Data in browser storage
   localStorage.setItem("moviedata", JSON.stringify(movieList));
   localStorage.setItem("cacheTimestamp", Date.now()); // Update cache timestamp

   // Render the movies on the page
   renderMovies(movieList);
 } catch (error) {
   movieUnavailableTxt.innerHTML =
     "An error occurred while fetching movies. <br /> Please try again later.";
   movieUnavailableTxt.style.display = "block";
   console.error(error);
 }
};

// Function to render movies on the page
const renderMovies = (movies) => {
 resultsContainer.innerHTML = ""; // Clear the existing movies
 movieUnavailableTxt.style.display = "none"; // Hide the "No movies found" message
 moviesReturnedOnSearch = []; // Clear the movies returned on search array

 movies.forEach((movie) => {
   resultsContainer.innerHTML += `
     <div class="movie-cards">
       <img src="${movie.image}" alt="movie image" class="movie-image" />
       <h2 class="title">${movie.title}</h2>
       <p class="plot">${movie.description}</p>
       <p class="date">${movie.year}</p>
     </div>
   `;

   moviesReturnedOnSearch.push(movie); // Add the movies that are a result to the search input value
 });
};

const cacheTimestamp = localStorage.getItem("cacheTimestamp");
const expirationDuration = 21600000; // 6 hours in milliseconds

// Check if cache has expired or data is not available
if (
 !cacheTimestamp ||
 Date.now() - parseInt(cacheTimestamp) > expirationDuration
) {
 // Cache expired or data not available, fetch movies again
 fetchMovies();
} else {
 // Use cached movie data
 movieList = JSON.parse(localStorage.getItem("moviedata"));
 renderMovies(movieList);
}

// Event listener and handler for search bar input
searchBar.addEventListener("input", (event) => {
 searchValue = event.target.value.trim().toLowerCase();

 // Filter movies based on search input
 const filteredMovies = movieList.filter((movie) =>
   movie.title.toLowerCase().includes(searchValue),
 );

 // Render the filtered movies on the page
 renderMovies(filteredMovies);

 if (moviesReturnedOnSearch.length <= 0) {
   movieUnavailableTxt.style.display = "block"; // Show the "No movies found" message if no movies match the search
 }
});

Заключение

В этом руководстве мы рассмотрели реализацию функции живого поиска в JavaScript с использованием API. Следуя описанным шагам, вы можете создать динамический поиск, предоставляющий результаты в режиме реального времени по мере того, как пользователи вводят текст в строку поиска.

Внедрив функцию живого поиска на свой веб-сайт, вы можете повысить вовлеченность пользователей и повысить удобство использования вашего веб-сайта или приложения. Пользователи оценят возможность быстрого и удобного поиска нужной информации без необходимости перезагрузки страницы.

Благодаря знаниям, полученным из этого руководства, вы хорошо подготовлены для эффективной реализации функции живого поиска в JavaScript. Воспользуйтесь мощью динамического поиска и создайте удобный пользовательский интерфейс, который оставит неизгладимое впечатление.

Удачного кодирования!

Первоначально опубликовано на https://dev.to 4 августа 2023 г.