Здравствуйте у меня вопрос по поводу писания живого поиска

Рейтинг: 0Ответов: 1Опубликовано: 27.07.2023

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

...А тем кто захочет помочь и внести правки в мою вёрстку, то им опишу проблему - я написал вёрстку и захотел, что бы на нём присутствовал живой поиск. Так как сам пока не умею делать такие вещи, и в добавок у сторонних ресурсах не было информации подходящий мне, то пришлось "спросить " у ChatTGP, с помощью него я добавил в мою вёрстку поисковик однако он не правильно взаимодействует с input, как вы видите при наборе слова adidas,  input поднимается, это как я считаю из-за id="results-container".

...Нужно, чтобы визуальная работа поисковика была похожа на, поисковик wildberries.

const searchInput = document.getElementById('inp');
const resultsContainer = document.getElementById('results-container');
let typingTimer;
const doneTypingInterval = 300;

// Реальные результаты поиска и их URL
const resultsDictionary = [
  { title: 'Adidas Shoes', url: 'https://www.example.com/adidas-shoes' },
  { title: 'Apple Watch', url: 'https://www.example.com/apple-watch' },
  { title: 'Amazon Kindle', url: 'https://www.example.com/amazon-kindle' },
  { title: 'Samsung Galaxy', url: 'https://www.example.com/samsung-galaxy' },
  // Добавьте другие результаты поиска с соответствующими заголовками и URL
];

// Обработчик ввода текста в поле поиска
searchInput.addEventListener('input', function (e) {
  const searchTerm = e.target.value.trim().toLowerCase();

  if (searchTerm === '') {
    // Если поле ввода пустое, очищаем контейнер с результатами
    resultsContainer.innerHTML = '';
  } else {
    const filteredResults = resultsDictionary.filter(result => result.title.toLowerCase().startsWith(searchTerm));
    displayResults(filteredResults);
  }
});

function displayResults(results) {
  resultsContainer.innerHTML = '';

  if (results.length === 0) {
    resultsContainer.innerHTML = '<p>Ничего не найдено</p>';
  } else {
    results.forEach(result => {
      const resultElement = document.createElement('div');
      resultElement.innerHTML = `<p class="result-item">${result.title}</p>`;
      resultElement.addEventListener('click', function () {
        // При клике на результат перенаправляем на другую страницу
        redirectToPage(result.url);
      });
      resultsContainer.appendChild(resultElement);
    });
  }
}

// Функция для перенаправления на другую страницу по выбранному результату
function redirectToPage(url) {
  window.location.href = url;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background-color: #66CDAA;
}

#box {
    display: flex;
    justify-content: space-between; 
    align-items: center; 
    padding: 15px 15px; 
    max-width: calc(100% - 200px); 
    margin: 30px auto; 

    @media screen and (max-width: 1200px) {
        max-width: calc(100% - 150px); 
    }

    @media screen and (max-width: 800px) {
        flex-direction: column; 
        align-items: center; 
        max-width: 80%; 
        padding: 15px 30px; 
    }
}

#box .Wild {
    font-size: 50px;
}

i.fa {
    font-size: 25px; 
    cursor: pointer;
    margin-right: 5px; 
}

#box input {
    flex: 1; 
    height: 45px;
    margin-left: 20px;
    padding-left: 10px; 
    border-radius: 20px;
    width: 500px; 
}

#box button {
    height: 45px;
    padding: 0 20px;
    background-color: #3366FF;
    color: white;
    border: none;
    border-radius: 20px;
    font-size: 20px;
    cursor: pointer;
}

#box .Adress {
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: pointer;
    margin-left: 60px;
}

#box .Adress i {
    font-size: 25px;
}

#box .Adress p {
    font-size: 20px;
}

#goods {
    width: 100%;
    margin: 35px auto 100px;
    background-color: white; 
    border: 2px solid;
    border-radius: 30px;
    padding: 15px;
}

.goods1 {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px;
}

#goods .row {
    width: 100%;
    max-width: calc(25% - 20px);
    height: 250px;
    margin-top: 40px;
    border-radius: 15px;
    margin-bottom: 40px;
    overflow: hidden;
}

.row img {
    transition: 1s; 
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.row img:hover {
    transform: scale(1.2); 
    cursor: pointer;
    filter: brightness(70%);
}

#results-container { 
    /* margin-top: 20px; */
       overflow: hidden;
}

@media screen and (max-width: 1200px) {
    #box {
        padding: 0 10px;
    }

    #goods {
        padding: 10px;
    }

    .goods1 {
        justify-content: center;
    }

    #goods .row {
        max-width: calc(33.33% - 20px);
    }
}
<!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="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="css/style.css">
    <title>Document</title>
</head>
<body>
    <div id="box">
        <div class="Wild"> <p>Wildberries</p> </div>

        <div>
            <!-- <i class="fa fa-search" aria-hidden="true"></i> -->
            <input id="inp" type="text" placeholder="Ես փնտրում եմ...">
            <div id="results-container">
            </div>
        </div>

        <div class="Adress"> <i class="fa fa-map-marker" aria-hidden="true"> </i> <br> <p> Հասցեներ </p> </div>
        <div class="Adress"> <i class="fa fa-map-marker" aria-hidden="true"> </i> <br> <p> Առաքում  </p> </div>
        <div class="Adress"> <i class="fa fa-user" aria-hidden="true"></i> <br> <p> Օգտատեր  </p> </div>
        <div class="Adress"> <i class="fa fa-shopping-cart" aria-hidden="true"></i> <br> <p> Զամբյուղ </p> </div>
    </div>

    <div id="goods" style="text-align: center">
        <div class="goods1">
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/nm_beach.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/nm_beach.webp" alt=""></div>
        <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_adidas_1306_TV8585696.webp" alt=""></div>
        <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_sokolov_1306_TV859595.webp" alt=""></div>
        </div>

        <div class="goods1">
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_unison_1306_TV48596.webp" alt=""></div>
        <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_tecno_1306_TV4785966.webp" alt=""></div>
        <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_zagar3884955.webp" alt=""></div>
        <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_garden738455.webp" alt=""></div>
    <!-- </div> -->
        </div>
    </div>

    <script src="js/lab.js"></script>

Ответы

▲ 0

Добавил #results-container абсолютное позиционирование и сделал его по стилистике похожим на input, теперь вёрстка не дёргается.

В JS создал функцию, принимающую строку текста и отвечающую за создание новой строки в блоке результата. У input стили и обращение к нему в JS теперь по классу, так как сейчас при поиске ему добавляется класс, который изменяет его стили. Если бы id остался, то новый класс не смог бы заменять свойства id, потому что css считает стили id более предпочтительными, чем у класса.

const searchInput = document.querySelector('.input');
const resultsContainer = document.getElementById('results-container');
let typingTimer;
const doneTypingInterval = 300;

// Реальные результаты поиска и их URL
const resultsDictionary = [
  { title: 'Adidas Shoes', url: 'https://www.example.com/adidas-shoes' },
  { title: 'Apple Watch', url: 'https://www.example.com/apple-watch' },
  { title: 'Amazon Kindle', url: 'https://www.example.com/amazon-kindle' },
  { title: 'Samsung Galaxy', url: 'https://www.example.com/samsung-galaxy' },
  // Добавьте другие результаты поиска с соответствующими заголовками и URL
];

// Обработчик ввода текста в поле поиска
searchInput.addEventListener('input', function (e) {
  const searchTerm = e.target.value.trim().toLowerCase();

  if (searchTerm === '') {
    // Если поле ввода пустое, очищаем контейнер с результатами
    searchInput.classList.remove('input_active'); //Если в поле ничего нет, то класс удаляется
    resultsContainer.innerHTML = '';
  } else {
    const filteredResults = resultsDictionary.filter(result => result.title.toLowerCase().startsWith(searchTerm));
    displayResults(filteredResults);
  }
});

function displayResults(results) {
  resultsContainer.innerHTML = '';
  searchInput.classList.add('input_active'); //Если пользователь что-то ввёл, добавляется класс

  function createResult(result) { //Функция отвечающая за создание блока с результатом
    const resultElement = document.createElement('div');
    resultElement.innerHTML = `<p class="result-text">${result}</p>`;
    resultElement.classList.add('result-item');

    if (results.length !== 0) { //Обработчик не добавляется, если результатов поиска нет
      resultElement.addEventListener('click', function () { // При клике на результат перенаправляем на другую страницу
        redirectToPage(result.url);
      });
    }

    resultsContainer.append(resultElement);
  }

  if (results.length === 0) {
    createResult('Ничего не найдено');
  } else {
    results.forEach(result => {
      createResult(result.title);
    });
  }
}

// Функция для перенаправления на другую страницу по выбранному результату
function redirectToPage(url) {
  window.location.href = url;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background-color: #66CDAA;
}

#box {
    display: flex;
    justify-content: space-between; 
    align-items: center; 
    padding: 15px 15px; 
    max-width: calc(100% - 200px); 
    margin: 30px auto; 

    @media screen and (max-width: 1200px) {
        max-width: calc(100% - 150px); 
    }

    @media screen and (max-width: 800px) {
        flex-direction: column; 
        align-items: center; 
        max-width: 80%; 
        padding: 15px 30px; 
    }
}

#box .Wild {
    font-size: 50px;
}

i.fa {
    font-size: 25px; 
    cursor: pointer;
    margin-right: 5px; 
}

.input {
    flex: 1; 
    height: 45px;
    margin-left: 20px;
    padding-left: 10px; 
    border-radius: 20px;
    width: 500px; 
    border: none;
}

#box button {
    height: 45px;
    padding: 0 20px;
    background-color: #3366FF;
    color: white;
    border: none;
    border-radius: 20px;
    font-size: 20px;
    cursor: pointer;
}

#box .Adress {
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: pointer;
    margin-left: 60px;
}

#box .Adress i {
    font-size: 25px;
}

#box .Adress p {
    font-size: 20px;
}

#goods {
    width: 100%;
    margin: 35px auto 100px;
    background-color: white; 
    border: 2px solid;
    border-radius: 30px;
    padding: 15px;
}

.goods1 {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px;
}

#goods .row {
    width: 100%;
    max-width: calc(25% - 20px);
    height: 250px;
    margin-top: 40px;
    border-radius: 15px;
    margin-bottom: 40px;
    overflow: hidden;
}

.row img {
    transition: 1s; 
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.row img:hover {
    transform: scale(1.2); 
    cursor: pointer;
    filter: brightness(70%);
}

#results-container {
    position: absolute;
    overflow: hidden;
    margin-left: 20px;
    border-radius: 0 0 20px 20px;
    width: 500px;
    background: #fff;
    box-shadow: 0 10px 10px rgba(0,0,0,.2);
}

.input_active {
    border-radius: 20px 20px 0 0;
}

.result-item {
    padding-left: 10px;
    height: 22px;
}

.result-item:hover {
    background: #f6f6f9;
}

@media screen and (max-width: 1200px) {
    #box {
        padding: 0 10px;
    }

    #goods {
        padding: 10px;
    }

    .goods1 {
        justify-content: center;
    }

    #goods .row {
        max-width: calc(33.33% - 20px);
    }
}
<div id="box">
        <div class="Wild"> <p>Wildberries</p> </div>

        <div>
            <input class="input" type="text" placeholder="Ես փնտրում եմ...">
            <div id="results-container">
            </div>
        </div>

        <div class="Adress"> <i class="fa fa-map-marker" aria-hidden="true"> </i> <br> <p> Հասցեներ </p> </div>
        <div class="Adress"> <i class="fa fa-map-marker" aria-hidden="true"> </i> <br> <p> Առաքում  </p> </div>
        <div class="Adress"> <i class="fa fa-user" aria-hidden="true"></i> <br> <p> Օգտատեր  </p> </div>
        <div class="Adress"> <i class="fa fa-shopping-cart" aria-hidden="true"></i> <br> <p> Զամբյուղ </p> </div>
    </div>

    <div id="goods" style="text-align: center">
        <div class="goods1">
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/nm_beach.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/nm_beach.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_adidas_1306_TV8585696.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_sokolov_1306_TV859595.webp" alt=""></div>
        </div>

        <div class="goods1">
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_unison_1306_TV48596.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_tecno_1306_TV4785966.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_zagar3884955.webp" alt=""></div>
            <div class="row"><img src="https://static-basket-01.wb.ru/vol1/crm-bnrs/bners1/desk_garden738455.webp" alt=""></div>
        </div>
    </div>