Reputation: 68
I'm in a situation where I have an EventListener
on two elements, and they have the same handler. The EventListeners
are added inside of a function and the handler takes in arguments.
When one of these elements are clicked the EventListeners
on both elements should be removed.
Example code:
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)
})
}
I've tried to pass the function callHandler
as an argument but that did not work.
Upvotes: 1
Views: 745
Reputation: 7913
There are many strategies you could use to solve this issue. The simplest may be the fact that references to elements with IDs are already available in the global scope, so you can reference them as regular variables or from the window
object:
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>
Another option is to simply use onclick
rather than adding and removing event listeners which will work the same way (it only prevents multiple click events on an element from being listened to):
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>
Another option, though perhaps the trickiest to implement, is to pass references to the elements in your function calls by using something like .bind()
The scopes get a bit unwieldy, I'm not sure it's achievable with your arrow functions.
ele1.addEventListener('click', handler.bind(this, ele2, x))
Upvotes: 1