我正在开发一个 JS 类来生成响应式导航栏,但在设置处理在不同时间显示和隐藏不同元素的事件时遇到问题。该结构在以下 HTML 中定义。
<div class="menu-container" id="menu1">
<div class="menu-label"> Menu 1 Label </div>
<div class="menu-list-container">
<div class="menu-item"> Item 1 </div>
<div class="menu-item"> Item 2 </div>
<div class="menu-item"> Item 3 </div>
</div>
</div>
<script>
setListeners();
</script>
所以我们有一个容器,里面有一个标签和一个列表容器,列表容器里面有一个菜单项列表。
目标是切换 display
menu-list-container
的属性(property)之间none
和block
基于鼠标事件。我想要的是附加一个 mouseover
事件至menu-label
其中“显示”menu-list
,即集合display: block
然后是 mouseout
事件至menu-container
这显然颠倒了 display
的设置.
我的 JS 执行此操作如下:
function setListeners(){
var menCon = document.getElementById("menu1");//1 div
var menLab = menCon.children[0];// 1 div
var menList = menLab.nextElementSibling;//1 div
var menItems = menList.children;// HTMLCollection
console.log(menCon);
console.log(menLab);
console.log(menList);
console.log(menItems);
menLab.addEventListener("mouseover",showList,false);
menCon.addEventListener("mouseout",hideList,false);
}
function showList(evt){
var list = evt.target.nextElementSibling;
list.style.display = "block";
}
function hideList(evt){
console.log(evt.target)
var list = evt.target.children.item(1);
list.style.display = "none";
}
据我所知,showList
没有任何问题。监听器函数,但是hideList
给我带来了各种各样的问题。在调试时我注意到了一些事情:首先,我认为 menu-container
可能无法正确调整大小,但如果 FireFox 开发人员工具值得信赖,它确实会在“显示” menu-list-container
时调整大小。 ;但是,向下移动鼠标(将鼠标悬停在 menu-label
上)我可以看到 hideList
退出 menu-container
内的每个单独元素后调用函数通过调用console.log()
在那个函数中。事实上,evt.target
是这些元素,这意味着事件监听器是由这些元素激活的,而不是由 menu-container
激活的。元素,考虑到我明确地将事件附加到容器而不是其他任何东西,这对我来说非常令人困惑。最重要的是,在 FireFox 检查器中,您可以看到哪些元素附加了事件,并且它确认 menu-container
元素有 mouseout
事件,仅此而已。
显然我对addEventListener
有一个根本性的误解。有效,但我似乎无法理解为什么我正在做的事情会这样工作。我需要一些启发!
最佳答案
mouseover
和 mouseout
泡沫从后代到他们的祖先,所以(例如)如果你有:
<div><span>foo</span> <span>bar</span></div>
...你有一个mouseout
div 上的处理程序,您将得到 mouseout
当鼠标光标移出 div 内的 span 时发生的事件。尝试一下:
document.querySelector(".example").addEventListener("mouseover", function() {
console.log("div received mouseover");
});
document.querySelector(".example").addEventListener("mouseout", function() {
console.log("div received mouseout");
});
div.example {
border: 1px solid #ddd;
padding: 4px;
}
div.example span {
border: 1px solid #aaa;
}
<div class="example"><span>foo</span> <span>bar</span></div>
如果您想要一个不冒泡的事件,请使用 mouseenter
(当鼠标进入该特定元素时)和 mouseleave
(当它离开该特定元素时)。尝试一下:
document.querySelector(".example").addEventListener("mouseenter", function() {
console.log("div received mouseenter");
});
document.querySelector(".example").addEventListener("mouseleave", function() {
console.log("div received mouseleave");
});
div.example {
border: 1px solid #ddd;
padding: 4px;
}
div.example span {
border: 1px solid #aaa;
}
<div class="example"><span>foo</span> <span>bar</span></div>
关于javascript - JS addEventListener() 困惑,好像是递归地添加给children?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48550084/