问题描述
我希望当鼠标移过id1时,显示id2,当鼠标离开id1时,显示id2。问题如下:
1.当鼠标从id1移动到id2时,id从显示变为不显示,然后变为显示。
2.当鼠标从id2移动到id1时,id2的显示变为无显示,然后变为显示。
希望鼠标在id1或id2上移动时,id2始终显示,不会改变。
脚本类型=' text/JavaScript ' src=' http :https://code . jquery.com/jquery-1 . 12 . 4 . js '/script div id=' id1 ' style=' width :800 px;高度:400 px;background-color : # F23 ' div id=' id2 ' style=' width :400 px;高度:300 px;背景-color : # 0 F8;display:none'/div/div script type=' text/JavaScript ' $(' # id1 ')。mouseover(function(){$(this))。儿童()。fade in(1000);}).mouseout(函数(){$(this))。儿童()。fade out(1000);});/脚本
问题的解决方案。
在问题分析开始时,当鼠标从id1移动到id2时,会为id1触发mouseout事件,因为鼠标从id2移到id1,所以显示的是id2而不是显示的。然后,当鼠标移动到id2时,id2上触发了鼠标悬停事件。由于冒泡机制,id2上的mouseover事件在冒泡到id1之前被触发。同样的,当鼠标从id2移动到id1时,针对id2触发mouseout事件,或者因为冒泡机制,将mouseout事件传输到id1,id2从显示变为非显示,然后在鼠标移动到id1之前触发mouseover事件,然后id2从非显示变为显示。
看来,归根结底,以上问题是为了防止鼠标从id1移动到id2时出现id1的mouseout事件。当鼠标从id2移动到id1时,防止id2的mouseout事件在id1上冒泡。那么这个问题就不能简单地通过防止起泡来解决。
为了解决这个问题,jQuery提供了mouseenter和mouseleave方法。所以JS代码改成了下面这样,很好的解决了这个问题。
$('#id1 ')。mouseenter(function(){$(this))。儿童()。fade in(1000);}).mouseleave(函数(){$(this))。儿童()。fade out(1000);});很多地方都引入了鼠标进入、鼠标离开、鼠标悬停和鼠标退出,所以就复制粘贴了一个。
/*********************************************************/
1 .鼠标悬停和鼠标进入。
每当鼠标指针经过选定的元素或其子元素时,就会触发mouseover事件。
只有当鼠标指针经过选定的元素时,才会触发mouseenter事件。
2 .鼠标移出和鼠标离开。
无论鼠标指针离开选定元素还是任何子元素,都会触发mouseout事件。仅当鼠标指针离开选定元素时,才会触发mouseleave事件。
/*********************************************************/
现象确实是这个现象,但是过程有点模糊,我的理解如下:
当鼠标指针移动到所选元素时,将触发mouseover事件。众所周知,当鼠标指针从选中元素移动到其子元素时,首先会触发选中元素的mouseover事件,然后子元素的mouseover事件会冒泡到选中元素。此时,它相当于所选元素先执行mouseout事件,然后执行mouseover事件。
要验证,请按如下方式更改代码。
脚本类型=' text/JavaScript ' src=' http :https://code . jquery.com/jquery-1 . 12 . 4 . js '/script div id=' id1 ' style=' width :800 px;高度:400 px;background-color : # F23 ' div id=' id2 ' style=' width :400 px;高度:300 px;背景-color : # 0 F8;位置:绝对;' top:300px'/div/div script type=' text/JavaScript ' $(' # id1 ')。mouseover(function(){//$(this))。儿童()。fade in(1000);console . log(' a ');}).mouseout(function(){//$(this))。儿童()。fade out(1000);console . log(' b ');});/script鼠标从页面移动到id1,然后从id1移动到id2。控制台输出如下。
可以看到id1先后调用了mouseover、mouseout、mouseover事件,和上面的分析完全一样。
鼠标进入和鼠标离开的实现分析。
原理分析
从上面的分析我们可以看出,要实现mouseenter和mouseleave的效果,当鼠标从选中元素移动到其子元素时,选中元素不执行子类冒泡的mouseout事件或mouseover事件,当鼠标从选中元素移动到选中元素时,选中元素不执行子类冒泡的mouseover事件或mouseout事件。
为了达到上述效果,我们需要一个事件对象的relatedTarget属性,用于判断mouseover和mouseout事件目标节点的相关节点的属性。简单来说,当鼠标悬停事件被触发时,relatedTarget属性表示鼠标刚刚离开的节点,当鼠标退出事件被触发时,它表示鼠标移动到的对象。MSIE不支持该属性,但它有替代属性,即fromElement和toElement。此外,我们需要contains方法来确定一个对象是否包含在另一个对象中。
这样,当鼠标移动时,需要判断以下两项。
1.要调用mouseover,只需要判断relatedTarget是否是所选元素的子元素,如果是,则不执行(从所选元素的子元素移动到所选元素时,不会执行mouse over;当从所选元素移动到所选元素的子元素时,冒泡的鼠标悬停);未执行);
2.要调用mouseout,只需要判断relatedTarget是否是所选元素的子元素,如果是,则不执行(从所选元素的子元素移动到所选元素时,子元素冒泡的mouseout不执行;当从所选元素移动到所选元素的子元素时,鼠标悬停);未执行);
实施程序
判断两个元素之间是否存在包含关系。
contains函数封装在jquery中,如下所示。
可以简化如下。
//判断这两个a包含b函数是否包含(a,b) {return a. contains?a!=b a .包含(b) :(a .比较文件位置(b)16);}compareDocumentPosition位置的介绍。
这个方法是DOM Level 3规范的一部分,它允许您确定两个DOM Node之间的相互位置。这个方法比。包含()。这种方法的一个可能的应用是将domnodes按详细而精确的顺序进行排序。nodea返回的信息。comparedocumentposition (nodeb)描述如下:
位序列号含义
从上面,我们可以理解为什么应该写成a.comparedocumentation位置(b) 16,因为如果节点a包含节点b,它将返回16,1616=1,其他情况将导致0。
获取兼容性的相关目标。
为了兼容各种浏览器,参考jquery源代码,编写以下代码,获取mouseover和mouseout事件目标节点相关节点的relatedTarget属性。
函数GetRelated(e){ var related;var type=e . type . tolowercase();//获取事件名称if(类型=' mouse over '){ related target=e . related target | | e . from element } else if(类型=' mouse out '){ related=e . related target | | e . to element }返回related;}改进鼠标悬停和鼠标移出。
改进鼠标悬停和鼠标移出,实现改进的鼠标进入和鼠标离开效果,所有代码如下。
!DOCTYPE html html head title/title/head dydiv id=' id1 ' style=' width :800 px;高度:400 px背景色: # F23 ' div id=' id2 ' style=' width :400 px;高度:300 px背景-颜色: # 0 F8;位置:绝对;'top:300px'/div/div脚本类型=' text/JavaScript ' src=' http :https://代码。jquery。com/jquery-1。12 .4 .js '/script脚本类型=' text/JavaScript '//判断两个a中是否包含b函数包含(a,b){返回包含什么?a!=b a。包含(b) :(一。比较文件位置(b)16人;}函数getRelated(e){ var related;var类型=e . type。tolowercase();//这里获取事件名字if(type=='鼠标悬停'){ related=e . related target | | e . from ElEMENT } else if(type='鼠标移出'){ related=e . related target | | e . to ElEMENT }返回相关;} $(function(){ $(“# id1”).鼠标悬停(函数(e){//判断鼠标从哪移到id1上面var related=getRelated(e);//如果有关系的是id1的子元素id2,即从子元素id2移动到id1,或是有关系的为id1,即从id1移动到其子元素id2上面,则不进行任何操作,否则进行相应的操作如果(这个!=相关!包含(此,相关)){控制台。日志('鼠标悬停');}}).mouseout(函数(e){//判断鼠标要从id1上面移动到哪去?var related=getRelated(e);//如果有关系的是id1,即当id1从其子元素移动到id1上,或是有关系的是id2,即从id1上移动到其子元素,不进行任何操作,否则进行相应的操作如果(这个!=相关!包含(此,相关)){控制台。日志('鼠标移出');}});});/脚本/正文/html测试,鼠标移动路线如下图路线
由控制台可以很看出,此刻的鼠标悬停和鼠标移出已经完全具备移入与离开事件效果效果。
代码的封装
如果每次进行这样的操作,都需要加载框架或是写很多代表,将是件繁琐的事,为了便于以后操作,进行了适当的封装,模拟Jquery,生成自己的移入与老鼠叶。代码封装到dqMouse.js文件中,如下:
(函数(w){var dqMouse=function(obj) {//函数体返回新的DQMouse。fn。init(obj);} DQMouse。fn=DQMouse。原型={//扩展原型对象obj:null,dqMouse: '1.0.0 ',init:函数{这个。obj=obj归还这个;},包含:函数(a,b){ 0返回包含什么?a!=b a。包含(b) :(一。比较文件位置(b)16人;},getrelated :函数(e){ var related;var类型=e . type。tolowercase();//这里获取事件名字if(type=='鼠标悬停'){ related=e . related target | | e . from ElEMENT } else if(type='鼠标移出'){ related=e . related target | | e . to ElEMENT }返回相关;},超过:函数(fn){ var obj=this。objvar _ self=thisobj。onmouseover=function(e){ var related=_ self。getrelated(e);如果(这个!=相关!_self.contains(this,related)){ fn();} } return _ self},out :函数(fn){ var obj=this。objvar _ self=thisobj。onmouseout=function(e){ var related=_ self。getrelated(e);如果(obj!=相关!_self.contains(obj,related)){ fn();} } return _ self} } dqmouse。fn。初始化。prototype=dqmouse。fn;window.dqMouse=window .$ $=dqMouse})(窗口);调用的源文件如下:
div id=' id1 ' style=' width :800 px;高度:400 px背景色: # F23 ' div id=' id2 ' style=' width :400 px;高度:300 px背景-颜色: # 0 F8;位置:绝对;'top:300px'/div/div脚本类型=' text/JavaScript ' src=' http : dq mouse。js '/script脚本类型=' text/JavaScript ' var id1=document。getelementbyid(' id1 ');$$(id1).over(function(){ console。日志('鼠标悬停');}).out(函数(){控制台。日志('鼠标移出');});/script以上所述是小编给大家介绍的射流研究…中鼠标悬停和鼠标移出多次触发问题如何解决的相关内容,希望对大家有所帮助!