非IE瀏覽器實現onmouseenter

來源:互聯網
上載者:User

每次遇到onmouseover事件的處理就頭疼。比如父標籤A裡面嵌套了兩個子標籤,分別為標籤A1和A2。假設你在父標籤A上綁定了mouseover事件,理想的狀態應該是:當滑鼠從A標籤外移到A標籤上,事件觸發。

但實際情況是,在以下幾種情況下,mouseover事件都會被觸發,為mouseover事件觸發(mouseout事件類別似)。

  1. 當滑鼠從A標籤外移到A標籤上。
  2. 當滑鼠從父標籤A移入子標籤B(或C)。
  3. 當滑鼠從子標籤B移入子標籤C(假設間距足夠小的話)。

之前一直是通過在事件處理函數裡面判斷觸發目前時間的targe是否指定節點來解決上面問題,問題是,當標籤嵌套層次比較多的時候,這個判斷過程就變得很麻煩,還會讓處理函數裡面多處一堆跟邏輯不相關的代碼。

請教了某同事,IE瀏覽器支援mouseenter事件,可以輕鬆搞定以上問題,剛好現在手頭做的東西也是只需要支援IE瀏覽器(\(^o^)/)。然後就想了,如果突然需求變更說要支援其他非IE瀏覽器了,那不就慘了(這也是很有可能發生的),像firefox、chrome都是不支援mouseenter的。那就只能自己試著去類比下了:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>在非IE瀏覽器裡類比mouseenter、mouseleave事件</title>
<style>
.outer{width:400px;height:300px;background:#ccc;}
.inner{float:left;width:150px;height:150px;margin:20px;background:#000;}
</style>
</head>
<body>

<div id="outer" class="outer">

<div id="innerA" class="inner"></div>
<div id="innerB" class="inner"></div>
</div>
<div id="output"></div>
</div>
</body>

<script>
var EventUtil = {
//事件綁定
addEvent:function(element,type,handler){

if(element.attachEvent){ //為IE瀏覽器

element.attachEvent("on"+type,handler);

}else if(element.addEventListener){ //firefox、chrome等瀏覽器

if(type=="mouseenter" || type=="mouseleave"){ //對“mouseenter”、“mouseleave”事件做單獨綁定處理

//利用“mouseover”、“mouseout”來類比“mouseenter”、“mouseenter”
var eType = (type=="mouseenter")?"mouseover":"mouseout";
element.addEventListener(eType,EventUtil.wrapHandler(handler),false);
}else{

element.addEventListener(type,handler,false);
}

}else{ //其他瀏覽器

element["on"+type] = handler;
}
},
//對事件處理函數進行封裝
//如果觸發事件的元素跟綁定事件的元素相同,則調用處理函數
wrapHandler:function(handler){

var func = function(event){

var target = event.target;
var parent = event.relatedTarget;

while(parent && parent!=this){ //

try{parent = parent.parentNode;}
catch(e){break;}
}
//parent不等於this,說明觸發事件的正是綁定事件的element本身
(parent!=this) && (handler.call(target,event));
};

return func;
},
//事件移除,省略
removeEvent:function(element,handler){

//這裡沒有任何東西
}
};
function $(id){return document.getElementById(id);}

EventUtil.addEvent($("outer"),"mouseenter",handler);
EventUtil.addEvent($("outer"),"mouseleave",handler);

//
function handler(e){

var event = null,target = null;
if(window.event){
event = window.event;
target = e.srcElement;
}else{
event = e;
target = e.target;
}
$("output").innerHTML += event.type+":"+target.id+"<br/>";
}
</script>

在firefox和IE 8裡簡單測試了下,順利運行,搞定!

以上只是簡單地在非IE瀏覽器裡類比了mouseenter和mouseleave事件,只是實驗下,代碼寫的有點挫各種見諒,主要的是實現的原理。

文章參考了另一篇博文:http://kb.cnblogs.com/a/1627921/,寫得不錯,就是不知道為什麼下面的“運行代碼”一直沒反應。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.