我有一个
forEach
循环,它获取页面上具有指定属性的任何元素的属性。它看起来像这样:
const cursorActionElements = document.querySelectorAll("[data-cursor]");
cursorActionElements.forEach((el) => {
const elAttr = el.getAttribute("data-cursor");
el.addEventListener('mouseover', () => {
console.log(elAttr)
});
});
一切正常。它遍历并获取所有具有
data-cursor
属性的元素,并将其值存储在 elAttr
变量中。但是,由于某种原因,如果目标的父级恰好 ALSO 有 data-cursor
属性,则它会同时返回目标的 data-cursor
值和 AND 其父级的 data-cursor
值。
我真的不知道如何解决这个问题。我想过检索
data-cursor
上的 mouseover
值,但是,这仅意味着我需要使用 另一个 事件列表器,它似乎会减慢我的网站速度。
请帮忙。
问题是因为事件在 DOM 中从子级传播到父级,因此每个元素都会触发一次事件处理程序。要解决此问题,您可以在传递给事件处理程序的事件上调用
stopPropagation()
。
另请注意,最好还从 Event 对象中读取
data
属性,以避免依赖事件处理程序中循环中设置的变量时可能出现的任何范围/闭包问题。
这是一个经过上述更改后的工作示例:
const cursorActionElements = document.querySelectorAll("[data-cursor]");
cursorActionElements.forEach((el) => {
el.addEventListener('mouseover', e => {
e.stopPropagation();
const elAttr = e.target.getAttribute("data-cursor");
console.log(elAttr)
});
});
<div data-cursor="foo">foo</div>
<div data-cursor="bar">
bar
<div data-cursor="foobar">
foobar
</div>
</div>