如何在forEach循环中仅获取目标元素而非父元素的属性?
解决方案:阻止
mouseover事件冒泡或改用非冒泡事件 你遇到的问题根源是事件冒泡:mouseover事件会沿着DOM树向上传播,当鼠标悬停在带有data-cursor的子元素上时,子元素的事件触发后,父元素的同名事件也会被依次触发,导致同时打印两个属性值。
下面是几种高效的解决方案:
方案1:改用mouseenter事件(推荐,代码改动最小)
mouseenter事件不会冒泡,只会在鼠标真正进入当前元素时触发,完全避免父元素事件被误触发的问题:
const cursorActionElements = document.querySelectorAll("[data-cursor]"); cursorActionElements.forEach((el) => { const elAttr = el.getAttribute("data-cursor"); el.addEventListener('mouseenter', () => { console.log(elAttr) }); });
方案2:在mouseover中阻止事件冒泡
如果必须保留mouseover事件(比如需要利用其冒泡特性做其他逻辑),可以在事件回调中调用event.stopPropagation()阻止事件向上传播:
const cursorActionElements = document.querySelectorAll("[data-cursor]"); cursorActionElements.forEach((el) => { const elAttr = el.getAttribute("data-cursor"); el.addEventListener('mouseover', (event) => { event.stopPropagation(); // 阻止事件冒泡到父元素 console.log(elAttr) }); });
方案3:使用事件委托(性能最优,支持动态元素)
如果页面中data-cursor元素较多或会动态生成,推荐用事件委托——只给一个父容器绑定一次事件,通过事件目标找到最内层的目标元素,这样能大幅减少事件监听器数量,提升性能:
// 可以替换成更接近目标元素的父容器(比如#content),减少事件触发范围 document.body.addEventListener('mouseover', (event) => { // 找到触发事件的元素链中最内层带有data-cursor的元素 const targetEl = event.target.closest('[data-cursor]'); if (targetEl) { console.log(targetEl.getAttribute('data-cursor')); } });
这种方式不需要提前获取所有data-cursor元素,新增的动态元素也能自动生效,同时避免了冒泡导致的重复触发问题。
内容的提问来源于stack exchange,提问作者Hazrd
相关产品推荐
相关产品推荐

