Реализация кнопки "показать еще"

77
15 ноября 2021, 02:10

Проблема в том, что в мой addEventListener попадают немного не те данные, и я не могу понять в чем дело, хоть и объявил функцию общую. Просто кода слишком много и не вижу смысла сюда копировать всё. Дело в том, что фильрую массив и полученный новый помещаю в функцию titlesOutput. Но так вот получается, что выводится то он нормальный и преобразованный, а эвент на кнопке выводит +15 элементов из списка старого, хотя ссылаюсь я на один и тот же изменённый.


//Показывает список фильмов
function setList(data) {
  let showMore = document.querySelector('.more'),
    filmsList = document.querySelector('.list'),
    movieArray = [],
    moreIndex = 15;
  titlesOutput(data);
  //Вывод первых 15 фильмов
  function titlesOutput(moviesList) {
    movieArray = [];
    //Проверка на количество выводимых фильмов
    //Чтобы не было конфликтов с неизвестными индексами элементов (если фильмов меньше 15)
    if (moviesList.length < 15) {
      moviesList.forEach(object => {
        let li = document.createElement('li');
        li.innerHTML = object.title;
        filmsList.appendChild(li);
      });
    } else {
      for (let i = 0; i < 15; i++) {
        let li = document.createElement('li');
        li.innerHTML = moviesList[i].title;
        filmsList.appendChild(li);
      }
    }
    //Занесение в локальный массив полученного после поиска массива из функции ниже.
    movieArray.push(...moviesList);
    console.log(movieArray);
    //Если фильмов в категории меньше 15, то скрыть кнопку "показать еще"
    if (movieArray.length < moreIndex + 15) {
      showMore.style.display = 'none';
    } else {
      showMore.style.display = 'block';
    };
    return movieArray;
  };
  showMore.addEventListener('click', function () {
    // Если невыведенных фильмов осталось меньше чем 15, то вывести оставшиеся и скрыть кнопку.
    if (movieArray.length - moreIndex < 15) {
      for (let i = moreIndex; i < movieArray.length; i++) {
        let li = document.createElement('li');
        li.innerHTML = movieArray[i].title;
        filmsList.appendChild(li);
        showMore.style.display = 'none';
        //Возвращение индекса в исходное состояние для следующих вызовов.
        moreIndex = 15;
      }
    } else {
      for (let i = moreIndex; i < moreIndex + 15; i++) {
        let li = document.createElement('li');
        li.innerHTML = movieArray[i].title;
        filmsList.appendChild(li);
      }
      //Прибавление к индексу чтобы выводить следующие 15 фильмов из категории.
      moreIndex += 15;
    };
  });
  //Вывод следущих 15 фильмов ( не знаю как избавиться от повторения кода )
  let searchInput = document.querySelector('.search');
  //Поиск при вводе в input
  searchInput.addEventListener('input', () => {
    let term = searchInput.value;
    filmsList.innerHTML = '';
    //Возвращение индекса в исходное состояние для следующих вызовов.
    moreIndex = 15;
    search(term);
  });
  //Сама вызываемая функция поиска
  function search(term) {
    //Фильтр элементов по значению из input
    let result = data.filter(e => e.title.toLowerCase().indexOf(term.toLowerCase()) > -1);
    titlesOutput(result);
  }
  //Поиск по тэгам
  let tagList = document.querySelector('.tags'),
    selectedTags = [];
  tagList.addEventListener('click', event => {
    let target = event.target
    filmsList.innerHTML = '';
    //Добавление тэгов в массив при клике на сам тэг
    if (target.tagName == 'A') {
      if (target.classList.contains('selected')) {
        //Удаление тэга из выбранных, если он был уже выбран до этого
        selectedTags.splice(selectedTags.indexOf(target.innerHTML, 0), 1);
        target.classList.remove('selected');
      } else {
        selectedTags.push(target.innerHTML);
        target.classList.add('selected');
      }
    }
    filter(selectedTags);
  });
  //Сам фильтр по тэгам.
  function filter(selectedTags) {
    //Фильтр по выбранным тэгам.
    let result = data.filter(e => selectedTags.every(tag => e.tags.includes(tag)));
    //Возвращение индекса в исходное состояние для следующих вызовов.
    moreIndex = 15;
    titlesOutput(result);
    return result;
  }
}

Таков вывод в браузере

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

Answer 1
  1. Вынесите addEventListener из titlesOutput (и, возможно, из setList, если эта функция вызывается больше, чем один раз).

  2. На одном уровне с addEventListener, заведите переменную, указывающую на массив, чьи элементы Вы хотите выводить в обработчике click.

  3. moreIndex объявите рядом с переменной из пункта 2.

READ ALSO
Как убрать фоновую заливку в svg

Как убрать фоновую заливку в svg

Есть svg, он соединен через use с тегом path, в котором нарисован логотип из линийНа странице он отображается полностью залитым, а нужно, чтобы...

76
input type range, noUiSlider не делает десятичные числа

input type range, noUiSlider не делает десятичные числа

Нужно сверстать вот такой input range, использую noUiSlider

204
JS Ajax Не отправляются данные с формы в файл php

JS Ajax Не отправляются данные с формы в файл php

На сайте установлена тема DiviВ ней я не разбираюсь, но задача была отправить форму на почту админу

165
Ошибка React #321

Ошибка React #321

Написал свой тестовый React-компонент, выложил на npm, попытался подкачать его в другой проект и при рендеринге выдает такое сообщение:

124