I'm having trouble removing a mouseover/mouseout listener inside a foor loop. Let's say I have a menu that on desktop and on hover shows a dropdown, but to open the dropdown I want it on click on mobile. I need to remove the hover on mobile because I don't want it to be doing both. Here's my main function that opens the dropdown:
addChildrenActive(i){
if(this.parent[i].classList.contains('b--nav-a__list-group__list-item--is-active')){
//removes class to hide the dropdown
} else {
//adds class to show the dropdown
}
}
on the other hand, I have the function responsible for the listeners:
navbarInteraction(){
if(this.isMobile){ //calculated via another function based on breakpoints that returns true
for (let i = 0; i < this.parent.length; i++) {
this.parent[i].addEventListener('click', e => {
e.preventDefault();
this.addChildrenActive(i)
});
this.parent[i].removeEventListener('mouseover', this.addChildrenActive(i));
this.parent[i].removeEventListener('mouseout', this.addChildrenActive(i));
}
} else {
for (let i = 0; i < this.parent.length; i++) {
this.parent[i].addEventListener('mouseover', e => {
this.addChildrenActive(i)
});
this.parent[i].addEventListener('mouseout', e => {
this.addChildrenActive(i)
});
}
}
}
The removeEventListeners when isMobile is not woking for me and I'm currently able to hover and click to show the dropdown. How should I solve this?
Thanks in advance!
As @Teemu indicated you have to use a named function because you need a reference to that function if you want to remove it from a listener.
So instead of writing an anonymous function inside the addEventListener() you supply it the name of a function you defined elsewhere - and most importantly not inside your loop.
For example:
parent[i].addEventListener('mouseover', e => {
this.addChildrenActive(i)
});
becomes
parent[i].addEventListener('mouseover', mouseOverHandler);
and it's named function
function mouseOverHandler(e)
{
console.log("mouse over", e.currentTarget);
}
You might have noticed the e parameter inside the function. This will be populated with data related to the event e.g. the name of the event or which element caused it.
This listener can then be removed using:
parent[i].removeEventListener('mouseover', mouseOverHandler);
Let me give you a more complete example:
class Navigation {
constructor() {
this.isMobile = false;
this.parent = document.querySelectorAll("div");
this.navbarInteraction();
}
navbarInteraction() {
for (let i = 0; i < this.parent.length; i++) {
this.parent[i].removeEventListener('mouseover', this.addChildrenActive);
this.parent[i].removeEventListener('click', this.addChildrenActive);
if (this.isMobile) {
this.parent[i].addEventListener('click', this.addChildrenActive);
} else {
this.parent[i].addEventListener('mouseover', this.addChildrenActive);
}
}
}
addChildrenActive(e) {
console.log("addChildrenActive()", e.currentTarget, e.type);
}
}
let navigation = new Navigation();
<div id="divA">DIV1</div>
<div id="divB">DIV2</div>
<input type="checkbox" onchange="navigation.isMobile=this.checked;navigation.navbarInteraction();">
<span>isMobile</span>