如何用原生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
相关产品推荐
相关产品推荐

