@Dubrovin

Как перезапустить функцию JS?

Делаю механизм поиска внутри выпадающего списка, есть функция refreshlist которая срабатывает при keyup в input поиска. Она сравнивает значение из input с каждой опцией выпадающего списка и если не находит совпадение - скрывает опцию (или отображает если находит). При небольшом списке (до 500 элементов) - всё работает отлично. Когда элементов около 1000 - начинаются "фризы" если начать печатать очень быстро в input.

Как сделать так, чтобы при возникновении события keyup, если предыдущая итерация не успела завершиться - то её выполнение прервалось и началось выполнение новой?
p.s. jQuery не использую, просьба дать ответ на нативном JS. Функция k.on - декоратор над addEventListener

Код:
this.refreshList = () => {
				let search = this.searchInput.input.value.toLowerCase();
				this.el.classList.add( '--noResults' );

				this.listItemAll.forEach( ( el ) => {
					if ( el.innerText.toLowerCase().indexOf( search ) === -1 ) {
									el.classList.add( '--hidden-xs' );
					} else {
									el.classList.remove( '--hidden-xs' );
									this.el.classList.remove( '--noResults' );
					}
				} );
			};

			k.on( this.searchInput.el, 'keyup', () => {
				this.refreshList();
			}, this );
  • Вопрос задан
  • 1032 просмотра
Решения вопроса 2
Stalker_RED
@Stalker_RED
Варианты:

1. Проверять внутри этого тяжелого форича не изменился ли инпут. Делать брейк, если изменился.

2. Использовать throttle/debounce. Примеров реализации полно.
https://www.google.com/search?q=throttle+debounce+js
Ответ написан
rockon404
@rockon404
Frontend Developer
По-хорошему отфильтрованные данные запрашиваются с сервера, а не фильтруются на клиенте.

Поставьте debounce на хандлер. Должно помочь:
const handleKeyUp = e => {
  // handler
};

k.on(this.searchInput.el, 'keyup',  _.debounce(handleKeyUp, 300), this);

если не хотите тянуть lodash
function debounce(f, ms) {

  let timer = null;

  return function (...args) {
    const onComplete = () => {
      f.apply(this, args);
      timer = null;
    }

    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(onComplete, ms);
  };
}

Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы