JS функция установки слишком много addEventListeners - PullRequest
0 голосов
/ 25 марта 2020

У меня есть одностраничное приложение (SPA) с функцией поиска, где я пытаюсь отслеживать, как пользователи взаимодействуют с панелью поиска в Adobe Analytics. Если я перейду к 5 различным «страницам» моего SPA, следующий код вызовет событие 6 раз. Кажется, addEventListener устанавливается, но не сбрасывается, если поиск не выполняется на «странице». Эти EventListeners, по сути, ставятся в очередь каждый раз, когда загружается «страница», и, как только поиск введен, все они запускаются одновременно, освобождая очередь.

Как я могу очистить eventListeners, если поиск НЕ выполняется и запускать это событие можно только после того, как поиск выполнен нажатием клавиши ввода?

Предположим, у меня есть код:

clearInterval(interval);
var interval = setInterval(function(){
    if (document.querySelector("form div[data-autoid='search_bar'] input")) {       
        inputField = document.querySelector("form div[data-autoid='search_bar'] input")
        inputField.addEventListener('keydown', searchEntered)
        clearInterval(interval);
    } 
}, 500);

function searchEntered(e) {
    if (e.key == "Enter") {
      console.log("search entered");
      var event = new CustomEvent('searchEntered');
     dispatchEvent(event);
    }
}

Ответы [ 3 ]

1 голос
/ 25 марта 2020

Если вы хотите удалить существующий прослушиватель событий, используйте EventTarget.removeEventListener().

. В качестве MDN-страницы нужно указать те же параметры type и listener, которые Вы перешли на addEventListener(). Если вы также передали параметры, вы также должны передать те же самые значения в removeEventListener():

Учитывая прослушиватель событий, ранее добавленный путем вызова addEventListener (), вы можете в конечном итоге прийти к точке, в которой вы нужно удалить это. Очевидно, что вы должны указать тот же тип и параметры слушателя для removeEventListener (), но как насчет параметров или параметров useCapture?

Хотя addEventListener () позволит вам добавлять одного и того же слушателя более одного раза для одного и того же типа если параметры отличаются, единственный параметр removeEventListener () проверяет флаг capture / useCapture. Его значение должно совпадать, чтобы удалить removeEventListener (), но другие значения не совпадают.

Обратите внимание, что невозможно добавить несколько идентичных слушателей к одному элементу. На странице MDN :

Если несколько идентичных EventListeners зарегистрированы в одной и той же EventTarget с одинаковыми параметрами, дублирующиеся экземпляры отбрасываются. Они не вызывают повторного вызова EventListener, и их не нужно удалять вручную с помощью метода removeEventListener ().

0 голосов
/ 25 марта 2020
var interval = setInterval(function(){
  var inputField = document.querySelector("form div[data-autoid='search_bar'] input");
  if (inputField && !inputField.dataset.searchEventAttached) {
    inputField.addEventListener('keydown', searchEntered);
    inputField.dataset.searchEventAttached = true;
  } 
  clearInterval(interval);
}, 500);
0 голосов
/ 25 марта 2020

Если вы добавляете прослушиватель событий в окно , он будет перехватывать все события нажатия клавиш на странице (назначение делегата), как только это произойдет, проверьте, не было ли оно вызвано Введите ключ и, если parentNode имеет атрибут data-autoid = 'search_bar'. Если это правда, отправьте ваше пользовательское событие.

Это продолжит работать, даже если DOM изменится

addEventListener('keydown', e => {
  if (e.key == 'Enter' && e.target.parentNode.dataset.autoid == 'search_bar') {
    console.log('search entered');
    const event = new CustomEvent('searchEntered');
    dispatchEvent(event);
  }
})
<div data-autoid='search_bar'> 
  Will trigger <input />
</div>

<label>
  Won't trigger <input />
</label>
...