Удалить прослушиватель событий, где обработчик не находится в области видимости - PullRequest
1 голос
/ 16 октября 2019

Я нахожусь в ситуации, когда у меня есть EventListener на двух элементах, и они имеют одинаковый обработчик. EventListeners добавляются внутрь функции, и обработчик принимает аргументы.

При нажатии на один из этих элементов EventListeners на обоих элементах следует удалить.

Пример кода:

const handler = (e, x, otherEle) => {
    e.target.removeEventListener('click', callHandler)
    otherEle.removeEventListener('click', callHandler)
    //callHandler is not defined
}

const myFunc = ()=>{
   let x = 7
   let ele1 = document.querySelector("#ele1")
   let ele2 = document.querySelector("#ele2")

   ele1.addEventListener('click', function callHandler(event){
     handler(event, x, ele2)
   })

   ele2.addEventListener('click', function callHandler(event){
    handler(event, x, ele1)
   })
}

Я пытался передать функцию callHandler в качестве аргумента, но это не сработало.

1 Ответ

1 голос
/ 16 октября 2019

Существует множество стратегий, которые можно использовать для решения этой проблемы. Самым простым может быть тот факт, что ссылки на элементы с идентификаторами уже доступны в глобальной области видимости, поэтому вы можете ссылаться на них как на обычные переменные или на объект window:

const handler = () => {
    console.log("calling handler only once");
    ele1.removeEventListener('click', handler)
    ele2.removeEventListener('click', handler)
}

const myFunc = () => {
   // These references to element IDs are already available in the global scope
   // let ele1 = document.querySelector("#ele1")
   // let ele2 = document.querySelector("#ele2")

   ele1.addEventListener('click', handler);
   ele2.addEventListener('click', handler);
}

myFunc();
div {
  border: 1px solid black;
  height: 50px;
  width: 50px;
}
<div id="ele1"></div>
<div id="ele2"></div>

Другой вариант - просто использовать onclick вместо добавления и удаления прослушивателей событий, которые будут работать одинаково (это предотвращает только несколько событий щелчка мышью)на элемент из прослушивания):

const handler = (e, x, otherEle) => {
    console.log("calling handler only once");
    e.target.onclick = null;
    otherEle.onclick = null;
}

const myFunc = ()=>{
   let x = 7
   let ele1 = document.querySelector("#ele1")
   let ele2 = document.querySelector("#ele2")

   ele1.onclick = function (event) {
     handler(event, x, ele2)
   }

   ele2.onclick = function (event) {
     handler(event, x, ele1)
   }
}

myFunc();
div {
  border: 1px solid black;
  height: 50px;
  width: 50px;
}
<div id="ele1"></div>
<div id="ele2"></div>

Другой вариант, хотя, возможно, и самый сложный для реализации, заключается в передаче ссылок на элементы в вызовах функций с использованием чего-то вроде .bind() Области видимости немного громоздкие, я не уверен, что это возможно с вашими функциями стрелок.

ele1.addEventListener('click', handler.bind(this, ele2, x))
...