我在删除一个遍循环中的mouseover/mouseout监听器时遇到了麻烦。假设我有一个菜单,在桌面和悬停时显示一个下拉菜单,但要打开下拉菜单,我希望它在移动设备上点击。我需要移除移动设备上的悬停,因为我不想让它同时做这两件事。下面是我打开下拉菜单的主要函数:
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
}
}
- 注意这个函数正在接收i作为参数。
另一方面,我有一个函数负责监听器:
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)
});
}
}
}
removeEventListeners当isMobile不为我工作时,我目前能够悬停并单击以显示下拉菜单。我该如何解决这个问题?
提前感谢!
正如@Teemu所指出的那样,您必须使用命名函数,因为如果您想从侦听器中删除该函数,则需要对该函数的引用。
因此,不是在addEventListener()
中编写匿名函数,而是向它提供您在其他地方定义的函数的名称-最重要的是不在循环中。
例如:
parent[i].addEventListener('mouseover', e => {
this.addChildrenActive(i)
});
是
parent[i].addEventListener('mouseover', mouseOverHandler);
命名为function
function mouseOverHandler(e)
{
console.log("mouse over", e.currentTarget);
}
您可能已经注意到函数内部的e
参数。这将填充与事件相关的数据,例如事件的名称或引起事件的元素。
这个监听器可以使用:
parent[i].removeEventListener('mouseover', mouseOverHandler);
让我给你一个更完整的例子:
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>