javascript - JS addEventListener() 困惑,好像是递归地添加给children?

标签 javascript html dom-events

我正在开发一个 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)之间noneblock基于鼠标事件。我想要的是附加一个 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/

相关文章:

javascript - 在 HTML 中制作 onclick 函数来执行 2 个函数

javascript - 需要在 typescript 中为以 "abcd_"开头的字符串编写正则表达式,并且仅允许字母数字字符和下划线

javascript - 如何逻辑划分TD cell

javascript - 使用 GPT API 时出现错误 400(在 JavaScript 中)

javascript - addEventListener 在 useEffect Hook 中不起作用

javascript - Flash Canvas 绘制图像不工作

html - 不悬停时图像变大

html - CSS - 文本溢出在 IE10 中不起作用

javascript - 使用 Angular UI-Router 时附加事件监听器

javascript - beforeunload 事件和 Content-Disposition=attachment