欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中mouseover和mouseout多次觸發(fā)問題如何解決

 更新時(shí)間:2016年06月06日 12:07:05   作者:我愛默小兜  
這篇文章主要介紹了JS中mouseover和mouseout多次觸發(fā)問題如何解決的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下

問題描述

我希望當(dāng)鼠標(biāo)移動(dòng)到id1上的時(shí)候,id2顯示,當(dāng)鼠標(biāo)離開id1的時(shí)候,id2顯示。問題如下:

1.當(dāng)鼠標(biāo)從id1上移動(dòng)到id2上的時(shí)候,id由有顯示變?yōu)椴伙@示,然后變?yōu)轱@示

2.當(dāng)鼠標(biāo)從id2上移動(dòng)到id1上的時(shí)候, id2有顯示變?yōu)椴伙@示,然后變?yōu)轱@示

我希望的是當(dāng)鼠標(biāo)在id1或者id2上移動(dòng)的時(shí)候,id2一直顯示,不發(fā)生變化。

<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="id1" style="width:800px; height:400px; background-color:#F23">
<div id="id2" style="width:400px; height:300px; background-color:#0F8; display:none;">
</div>
</div>
<script type="text/javascript">
$("#id1").mouseover(function(){
$(this).children().fadeIn(1000);
}).mouseout(function(){
$(this).children().fadeOut(1000);
});
</script>

這里寫圖片描述

問題解決辦法

最開始的問題分析,當(dāng)鼠標(biāo)從id1上移動(dòng)到id2上的時(shí)候,由于鼠標(biāo)由id2離開進(jìn)入id1,針對(duì)id1觸發(fā)了一個(gè)mouseout事件,于是id2有顯示變?yōu)椴伙@示,接著在鼠標(biāo)移動(dòng)到id2上,在id2上觸發(fā)了一個(gè)mouseover事件,由于冒泡機(jī)制,id2上的mouseover冒泡到id1之前,觸發(fā)了id1上的mouseover事件,然后id2由不顯示變?yōu)轱@示。同理,當(dāng)鼠標(biāo)從id2上移動(dòng)到id1上的時(shí)候,針對(duì)id2,觸發(fā)了一個(gè)mouseout事件,還是因?yàn)槊芭輽C(jī)制,mouseout事件傳到id1上,id2由顯示變?yōu)椴伙@示,接著鼠標(biāo)移動(dòng)到id1之前,觸發(fā)了一個(gè)mouseover事件,然后id2有不顯示變?yōu)轱@示。

看來,上面的問題歸根要解決的是,當(dāng)鼠標(biāo)由id1上移動(dòng)到id2上的時(shí)候,阻止id1的mouseout事件;當(dāng)鼠標(biāo)從id2上移動(dòng)到id1上的時(shí)候,阻止id2的mouseout事件冒泡到id1之上。那么僅僅通過阻止冒泡是解決不了問題。

為了解決這樣的問題,jQuery提供了mouseenter和mouseleave方法。于是將JS代碼改為如下,很好解決了問題。

$("#id1").mouseenter(function(){
$(this).children().fadeIn(1000);
}).mouseleave(function(){
$(this).children().fadeOut(1000);
});

很多地方都有介紹mouseenter、mouseleave與mouseover、mouseout,于是復(fù)制粘貼了一個(gè)。

/*********************************************************/

1.mouseover與mouseenter

不論鼠標(biāo)指針穿過被選元素或其子元素,都會(huì)觸發(fā) mouseover 事件。

只有在鼠標(biāo)指針穿過被選元素時(shí),才會(huì)觸發(fā) mouseenter 事件。

2.mouseout與mouseleave

不論鼠標(biāo)指針離開被選元素還是任何子元素,都會(huì)觸發(fā) mouseout 事件。
只有在鼠標(biāo)指針離開被選元素時(shí),才會(huì)觸發(fā) mouseleave 事件。

/*********************************************************/

現(xiàn)象確實(shí)是這個(gè)現(xiàn)象,但是過程說的有點(diǎn)模糊,我的理解如下:

當(dāng)鼠標(biāo)指針移動(dòng)到被選元素,會(huì)觸發(fā) mouseover 事件,這個(gè)大家都知道,當(dāng)鼠標(biāo)指針由被選元素移動(dòng)到其子元素,先是觸發(fā)被選元素的mouseout事件,然后子元素的mouseover事件冒泡到被選元素,此時(shí)相當(dāng)于被選元素先執(zhí)行了一個(gè)mouseout事件,然后執(zhí)行了一個(gè)mouseover事件。

為了驗(yàn)證將代碼改為如下

<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="id1" style="width:800px; height:400px; background-color:#F23">
<div id="id2" style="width:400px; height:300px; background-color:#0F8; position:absolute; top:300px;">
</div>
</div>
<script type="text/javascript">
$("#id1").mouseover(function(){
//$(this).children().fadeIn(1000);
console.log('a');
}).mouseout(function(){
//$(this).children().fadeOut(1000);
console.log('b');
});
</script>

鼠標(biāo)從頁面移動(dòng)到id1,然后由id1移動(dòng)到id2上,控制臺(tái)輸出如下圖

這里寫圖片描述 

可以看出id1先后調(diào)用了mouseover、mouseout、mouseover事件,正好和上面分析的相同。

mouseenter與mouseleave實(shí)現(xiàn)分析

原理分析

從上面分析,我們可以看出,要實(shí)現(xiàn)mouseenter與mouseleave的效果,就是當(dāng)鼠標(biāo)從被選元素移動(dòng)到其子元素上的時(shí)候,被選元素不執(zhí)行mouseout事件,也不執(zhí)行子類冒泡過來的mouseover事件,當(dāng)鼠標(biāo)從被選元素子元素移動(dòng)到被選元素上的時(shí)候,被選元素不執(zhí)行mouseover事件,也不執(zhí)行子類冒泡過來的mouseout事件。

要實(shí)現(xiàn)上面的效果,我們需要event對(duì)象的一個(gè)屬性relatedTarget,這個(gè)屬性就是用來判斷 mouseover和mouseout事件目標(biāo)節(jié)點(diǎn)的相關(guān)節(jié)點(diǎn)的屬性。簡單的來說就是當(dāng)觸發(fā)mouseover事件時(shí),relatedTarget屬性代表的就是鼠標(biāo)剛剛離開的那個(gè)節(jié)點(diǎn),當(dāng)觸發(fā)mouseout事件時(shí)它代表的是鼠標(biāo)移向的那個(gè)對(duì)象。由于MSIE不支持這個(gè)屬性,不過它有代替的屬性,分別是 fromElement和toElement。除此,我們還需要contains方法,來判斷一個(gè)對(duì)象是否包含在另外一個(gè)對(duì)象中。

這樣當(dāng)鼠標(biāo)移動(dòng),需要判斷以下兩條即可

1.調(diào)用mouseover,只需要判斷relatedTarget是否被選元素的子元素,如果是,則不執(zhí)行(當(dāng)于從被選元素子元素移動(dòng)到被選元素,不執(zhí)行mouseover;當(dāng)于從被選元素移動(dòng)到被選元素子元素,不執(zhí)行冒泡過來的mouseover);

2.調(diào)用mouseout,只需要判斷relatedTarget是否被選元素的子元素,如果是,則不執(zhí)行(當(dāng)于從被選元素子元素移動(dòng)到被選元素,不執(zhí)行子元素冒泡過來的mouseout;當(dāng)于從被選元素移動(dòng)到被選元素子元素,不執(zhí)行mouseover);

實(shí)現(xiàn)過程

判斷兩個(gè)元素是否存在包含關(guān)系

jquery中封裝了contains函數(shù)如下

這里寫圖片描述 

可以簡化為如下

//判斷兩個(gè)a中是否包含b
function contains(a,b){
return a.contains ? a != b && a.contains(b) :!!(a.compareDocumentPosition(b) & 16);
}

compareDocumentPosition介紹

這個(gè)方法是 DOM Level 3 specification 的一部分,允許你確定 2 個(gè) DOM Node 之間的相互位置。這個(gè)方法比 .contains() 強(qiáng)大。這個(gè)方法的一個(gè)可能應(yīng)用是排序 DOM Node 成一個(gè)詳細(xì)精確的順序。NodeA.compareDocumentPosition(NodeB)返回的信息描述如下:

比特 序號(hào) 意義

通過上面我們就可以理解為什么要寫成a.compareDocumentPosition(b) & 16因?yàn)槿绻?jié)點(diǎn) A 包含節(jié)點(diǎn) B,就會(huì)返回16,16&16=1,其他的情況結(jié)果都會(huì)0。

獲取兼容性性的relatedTarget

為了兼容各種瀏覽器,參考jquery源碼,寫出如下代碼,來獲取mouseover和mouseout事件目標(biāo)節(jié)點(diǎn)的相關(guān)節(jié)點(diǎn)的屬性relatedTarget。

function getRelated(e){
var related;
var type=e.type.toLowerCase();//這里獲取事件名字
if(type=='mouseover'){
related=e.relatedTarget||e.fromElement
}else if(type='mouseout'){
related=e.relatedTarget||e.toElement
}
return related; 
}

改進(jìn)mouseover和mouseout

改進(jìn)mouseover和mouseout以實(shí)現(xiàn)改進(jìn)mouseenter與mouseleave效果,所有代碼如下。

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="id1" style="width:800px; height:400px; background-color:#F23">
<div id="id2" style="width:400px; height:300px; background-color:#0F8; position:absolute; top:300px;">
</div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
//判斷兩個(gè)a中是否包含b
function contains(a,b){
return a.contains ? a != b && a.contains(b) :!!(a.compareDocumentPosition(b) & 16);
}
function getRelated(e){
var related;
var type=e.type.toLowerCase();//這里獲取事件名字
if(type=='mouseover'){
related=e.relatedTarget||e.fromElement
}else if(type='mouseout'){
related=e.relatedTarget||e.toElement
}
return related; 
}
$(function(){
$("#id1").mouseover(function(e){
//判斷鼠標(biāo)從哪移到id1上面
var related=getRelated(e); 
//如果related是id1的子元素id2,即從子元素id2移動(dòng)到id1,或是related為id1,即從id1移動(dòng)到其子元素id2上面,則不進(jìn)行任何操作,否則進(jìn)行相應(yīng)的操作
if(this!=related && !contains(this,related)){
console.log('mouseover');
}
}).mouseout(function(e){
//判斷鼠標(biāo)要從id1上面移動(dòng)到哪去?
var related=getRelated(e); 
//如果related是id1,即當(dāng)id1從其子元素移動(dòng)到id1上,或是related是id2,即從id1上移動(dòng)到其子元素,不進(jìn)行任何操作,否則進(jìn)行相應(yīng)的操作
if(this !=related && !contains(this,related)){
console.log('mouseout');
}
});
});
</script>
</body>
</html>

測(cè)試,鼠標(biāo)移動(dòng)路線如下圖路線

由控制臺(tái)可以很看出,此刻的mouseover和mouseout已經(jīng)完全具備mouseenter與mouseleave效果效果。

這里寫圖片描述 

代碼的封裝

如果每次進(jìn)行這樣的操作,都需要加載Jquery或是寫很多代表,將是件繁瑣的事,為了便于以后操作,進(jìn)行了適當(dāng)?shù)姆庋b,模擬Jquery,生成自己的mouseenter與mouseleave。代碼封裝到dqMouse.js文件中,如下:

(function(w){
var dqMouse = function(obj) {
// 函數(shù)體
return new dqMouse.fn.init(obj);
}
dqMouse.fn = dqMouse.prototype = {
// 擴(kuò)展原型對(duì)象
obj:null,
dqMouse: "1.0.0",
init: function(obj) {
this.obj=obj;
return this;
},
contains:function(a,b) {
return a.contains ? a != b && a.contains(b) :!!(a.compareDocumentPosition(b) & 16);
},
getRelated:function(e) {
var related;
var type=e.type.toLowerCase();//這里獲取事件名字
if(type=='mouseover'){
related=e.relatedTarget||e.fromElement
}else if(type='mouseout'){
related=e.relatedTarget||e.toElement
}
return related; 
},
over:function(fn){
var obj=this.obj;
var _self=this;
obj.onmouseover=function(e){ 
var related=_self.getRelated(e); 
if(this!=related && !_self.contains(this,related)){
fn();
}
}
return _self;
},
out:function(fn){
var obj=this.obj;
var _self=this;
obj.onmouseout=function(e){
var related=_self.getRelated(e); 
if(obj!=related && !_self.contains(obj,related)){
fn();
}
}
return _self;
}
} 
dqMouse.fn.init.prototype = dqMouse.fn;
window.dqMouse = window.$$= dqMouse;
})(window);

調(diào)用的源文件如下:

<div id="id1" style="width:800px; height:400px; background-color:#F23">
<div id="id2" style="width:400px; height:300px; background-color:#0F8; position:absolute; top:300px;">
</div>
</div>
<script type="text/javascript" src="dqMouse.js"></script>
<script type="text/javascript">
var id1=document.getElementById('id1');
$$(id1).over(function(){
console.log('mouseover');
}).out(function(){
console.log('mouseout');
}); 
</script>

以上所述是小編給大家介紹的JS中mouseover和mouseout多次觸發(fā)問題如何解決的相關(guān)內(nèi)容,希望對(duì)大家有所幫助!

相關(guān)文章

  • JS實(shí)現(xiàn)左右拖動(dòng)改變內(nèi)容顯示區(qū)域大小的方法

    JS實(shí)現(xiàn)左右拖動(dòng)改變內(nèi)容顯示區(qū)域大小的方法

    這篇文章主要介紹了JS實(shí)現(xiàn)左右拖動(dòng)改變內(nèi)容顯示區(qū)域大小的方法,涉及JavaScript實(shí)時(shí)響應(yīng)鼠標(biāo)事件動(dòng)態(tài)改變頁面元素屬性的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • 微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn)

    微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn)

    本文主要介紹了微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • js二維數(shù)組排序的簡單示例代碼

    js二維數(shù)組排序的簡單示例代碼

    本篇主要是對(duì)js二維數(shù)組排序的簡單示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2014-01-01
  • js手機(jī)號(hào)批量滾動(dòng)抽獎(jiǎng)實(shí)現(xiàn)代碼

    js手機(jī)號(hào)批量滾動(dòng)抽獎(jiǎng)實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了js手機(jī)號(hào)批量滾動(dòng)抽獎(jiǎng)實(shí)現(xiàn)代碼,s適用于年會(huì)等活動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • js?實(shí)現(xiàn)div拖拽拉伸完整示例

    js?實(shí)現(xiàn)div拖拽拉伸完整示例

    這篇文章主要為大家介紹了js?實(shí)現(xiàn)div拖拽拉伸完整示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Javascript字符串瀏覽器兼容問題分析

    Javascript字符串瀏覽器兼容問題分析

    這篇文章主要介紹了Javascript字符串瀏覽器兼容問題,實(shí)例形式對(duì)比分析了不兼容字符串與兼容字符串的區(qū)別,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-12-12
  • JavaScript常用數(shù)組去重實(shí)戰(zhàn)源碼

    JavaScript常用數(shù)組去重實(shí)戰(zhàn)源碼

    本文給大家分享js常用8種數(shù)組去重實(shí)戰(zhàn)源碼,針對(duì)每種方法通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-07-07
  • javascript中caller和callee詳解

    javascript中caller和callee詳解

    有些小伙伴可能會(huì)問caller,callee 是什么?在javascript 中有什么樣的作用?那么本篇會(huì)對(duì)于此做一些基本介紹。希望能夠?qū)Υ蠹依斫鈐avascript中的callee與caller有所幫助。
    2015-08-08
  • firefo xml 讀寫實(shí)現(xiàn)js代碼

    firefo xml 讀寫實(shí)現(xiàn)js代碼

    firefo xml 讀寫實(shí)現(xiàn) 不過要是你的xml要編碼成功還得在str前面加上xml頭,千萬別忘了啊。
    2009-06-06
  • 微信小程序中顯示倒計(jì)時(shí)代碼實(shí)例

    微信小程序中顯示倒計(jì)時(shí)代碼實(shí)例

    這篇文章主要介紹了微信小程序中顯示倒計(jì)時(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評(píng)論