You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用原生JavaScript实现mouseenter事件委托?

原生JavaScript实现mouseenter事件委托(等价于jQuery的$(document).on('mouseenter', '.demo', foo))

嘿,我完全懂你卡在哪了——mouseenter本身不冒泡的特性,加上事件委托的需求,确实比普通冒泡事件麻烦不少。jQuery偷偷帮我们把底层逻辑封装了,所以直接用很省心,但原生实现得自己把这些细节补全,我来给你拆解清楚:

核心原理:用mouseover模拟mouseenter的委托

因为mouseenter不支持冒泡,没法直接在document上监听子元素的mouseenter事件。jQuery的实现思路其实是监听冒泡的mouseover事件,然后通过判断鼠标的来源,模拟出mouseenter的触发条件。

等价的原生代码实现

// 监听document上的mouseover事件(因为它会冒泡)
document.addEventListener('mouseover', function(event) {
  // 找到触发事件的元素中,最接近(包括自身)匹配.demo的元素
  const targetElement = event.target.closest('.demo');
  
  // 如果没有匹配的元素,直接退出
  if (!targetElement) return;

  // 关键判断:鼠标是不是从目标元素的外部进入
  // relatedTarget是鼠标移动前所在的元素,如果它不在targetElement的范围内,就是真正的进入
  const isFromOutside = !targetElement.contains(event.relatedTarget);
  
  if (isFromOutside) {
    // 调用foo函数,把this绑定到匹配的.demo元素,同时传递事件对象
    foo.call(targetElement, event);
  }
});

关键细节解释

  • 为什么用mouseover?:只有冒泡事件才能做委托,mouseenter不冒泡,所以只能用它的冒泡版兄弟mouseover来兜底。
  • closest('.demo'):和jQuery事件委托的逻辑一致,确保我们找到的是真正需要触发事件的那个.demo元素(不管事件是从它的子元素还是自身触发的)。
  • contains(relatedTarget):这步是模拟mouseenter的核心——避免鼠标在.demo的子元素之间移动时重复触发事件。只有当鼠标从.demo元素的外部进入时,才执行处理函数。

额外注意

如果你的foo函数里用到了jQuery事件对象的扩展方法(比如event.originalEvent这类jQuery专属属性),可能需要做适配,但大部分基础的事件操作(比如preventDefault()、获取target)原生事件对象都能直接用。

内容的提问来源于stack exchange,提问作者Alvaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:05:16