-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mouseenter与mouseover为何这般纠缠不清? #1
Comments
感谢楼主的分享!讲得很详细很全面,但我有一点不明白的是文中说:“ul的父元素wrap(移入ul时,此时也是触发mouseenter事件的时候, 其实不一定,后面会说明)“,但是文中好像没有解释,请问在什么情况下不会触发mouseenter呢 |
@lazybonee 谢谢关注。 不好意思,可能这句话我描述的不是很清楚,这里的其实不一定,想表述的是:relatedTarget不一定是ul的父元素wrap, 不是说不会触发mouseenter哈。 文中其实也有解释 原因是,target的父元素有一定的占位空间的时后,我们这样写是没有太大问题的,但是反之,这个时候e.relatedTarget就可能是target元素的父元素,又或者是祖先元素中的某一个。 我写了一个例子,mouseover-parent, 你可以打开控制台,看下打印出来的信息,就可以发现打印出来的不是wrap元素,而是wrap-parent元素 |
@qianlongo 哦哦,明白了!谢谢你解释得这么仔细~ |
@lazybonee 嘿嘿 |
刚刚看到MDN上的,弄懂了
|
前言
原文地址
项目地址
mouseenter与mouseover的异同?
先来看一张图,对这两个事件有一个简单直观的感受。
再看看官网对mouseenter的解释
mouseenter | onmouseenter event
大概意思是说:当鼠标从元素的边界之外移入元素的边界之内时,事件被触发。而当鼠标本身在元素边界内时,要触发该事件,必须先将鼠标移出元素边界外,再次移入才能触发。(英语比较渣😶,凑合看哈)
大概意思是:和mouseover不同的是,mouseenter不支持事件冒泡 (英语比较渣😶,凑合看哈)
由于mouseenter不支持事件冒泡,导致在一个元素的子元素上进入或离开的时候会触发其mouseover和mouseout事件,但是却不会触发mouseenter和mouseleave事件
我们用一张动图来看看他们的区别(或者点击该链接体验)。
我们给左右两边的ul分别添加了
mouseover
和mouseenter
事件,当鼠标进入左右两边的ul时,mouseover
和mouseenter
事件都触发了,但是当移入各自的子元素li的时候,触发了左边ul上的mouseover事件,然而右边ul的mouseenter事件没有被触发。造成以上现象本质上是
mouseenter
事件不支持冒泡所致。如何模拟mouseenter事件。
关键因素: relatedTarget 要想手动模拟mouseenter事件,需要对mouseover事件触发时的事件对象event属性relatedTarget了解。
重新回顾一下文章最初的那张图,根据上面的解释,对于ul上添加的mouseover事件来说,relatedTarget只可能是
根据上面的描述,我们可以对relatedTarget的值进行判断:如果值不是目标元素,也不是目标元素的子元素,就说明鼠标已移入目标元素而不是在元素内部移动。
条件1: 不是目标元素很好判断
e.relatedTarget !== target(目标元素)
条件2:不是目标元素的子元素,这个应该怎么判断呢?
ele.contains
用法案例
那么利用contains这个api我们便可以很方便的验证条件2,接下来我们封装一个
contains(parent, node)
函数,专门用来判断node
是不是parent
的子节点用我们封装过后的
contains
函数再去试试上面的例子这个方法很方便地帮助我们解决了模拟mouseenter事件中的条件2,但是悲催的
ode.contains(otherNode)
,具有浏览器兼容性,在一些低级浏览器中是不支持的,为了做到兼容我们再来改写一下contains方法说了这么多,我们来看看用
mouseover
事件模拟mouseenter
的最终代码模拟mouseenter与原生mouseenter事件效果对比
html
css
javascript
效果预览
详细代码点击
代码示例点击
好了,我们已经通过mouseove事件完整的模拟了mouseenter事件,但是反过头来看看
对于ul上添加的mouseover事件来说,relatedTarget只可能是
我们通过排查2和3,最后只留下1,也就是mouseenter与mouseover事件一起触发的时机。既然这样我们为什么不像这样判断呢?
这样不是更加简单吗?,何必要折腾通过排查2和3来做?
原因是,target的父元素有一定的占位空间的时后,我们这样写是没有太大问题的,但是反之,这个时候
e.relatedTarget
就可能是target元素的父元素,又或者是祖先元素中的某一个。我们无法准确判断e.relatedTarget到底是哪个元素。所以通过排除2和3应该是个更好的选择。用mouseout模拟mouseleave事件
我们同样可以用上面封装的函数完成
详细代码点击
代码示例点击
结尾
原文地址
项目地址
The text was updated successfully, but these errors were encountered: