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

129
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, в котором нарисован логотип из линийНа странице он отображается полностью залитым, а нужно, чтобы...

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

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

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

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

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

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

216
Ошибка React #321

Ошибка React #321

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

172