jquery中的mouseenter实现理解
说在前面:首先说一下两者之间的区别,假设当前元素为element,mouseover事件具有冒泡特性,也就是说无论鼠标是从别的元素移动到element或者是从element的子元素移动到element都会触发mouseover事件。对于mouseenter事件,该事件没有冒泡特性,也就是说只有鼠标穿过该事件的时候才会触发mouseenter,如果鼠标一直在element内部“游走”,则不会触发mouseenter。具体的例子可以参考这个例子点击打开链接。
前提说完了,那么怎么使用mouseover实现mouseenter呢!
我们先来看看jQuery是怎么实现的,下面是jQuery中实现mouseenter以及mouseleave的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
jQuery.each({ mouseenter: "mouseover" , mouseleave: "mouseout" }, function ( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function ( event ) { var
ret, target = this , related = event.relatedTarget, handleObj = event.handleObj; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if
( !related || (related !== target && !jQuery.contains( target, related )) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this , arguments ); event.type = fix; } return
ret; } }; }); |
其他的倒不用看,关键在于if判断语句以及其中的组合条件,我们可以看到如果related是空或者undefined,则表示鼠标已经移动到window上面了,那么这时肯定已经穿过了该元素。为什么这么肯定,我们需要知道的是,底层这个判断语句是在mouseover事件中处理的,related返回的就是鼠标是从哪一个元素移动到element的,如果是window,那么肯定是“穿过”了element.
那么看第二个条件,related!==target && !jQuery.contains(target,related)。我们可以看到target=this;那么target指向的就是element,而related指向的则是由哪一个元素移动到element的,我们知道mouseover和mouseenter的区别在于,在从子元素中移动到element的时候是否触发相应的事件。这个情况就可以用related!==target && jQuery.contains(target,related)给过滤掉。
通过上一段的解释,我们知道这个条件的作用是,如果是从别的元素移动到element的时候,判断是否是从element的子元素移动过来的,如果是的话,则不触发事件,如果不是的话(!jQuery.contains(target,related)),则说明是从element的“外部”移动过来的,那么就表示鼠标已经穿过了element,就需要触发事件。
当然了这是jQuery下的实现,如果想用原生的js代码实现,可以结合relatedTarget实现。当然在IE中也许我们会用到fromElement以及toElement相结合的方式来实现。
这是自己学习过程中的记录了,我的理解可能有误,希望大家在评论中能够提出不足之处。
By Ygh1224 相互学习,相互进步!