也就是說,移到對象的子物件上,也算onmouseout了。但這往往會達不到我們想要的預期效果。這是由於javascript自身的冒泡特性導致的(即在子項目上觸發了事件,並冒泡到了父元素-堆棧後進先出演算法)。今天在網上搜了一下,找了以下的解決辦法(相容IE和Firefox)。
在IE下解決問題很簡單,用onMouseEnter、onMouseLeave來代替onMouseOver、onMouseOut就行了,他們的作用基本相同,但前者不會發生冒泡(如果用 jQuery的event事件,只要綁定mouseleave、mouseenter即可)。但firefox下並沒有onMouseEnter、onMouseLeave這兩個事件。那麼只能使用純js來解決IE及Firefox的相容性問題了:
原理:通過判斷觸發onMouseOut事件後,滑鼠到達的元素是不是包含在父元素資訊列(div)內,如果是就表示滑鼠還在資訊列(div)上,則不隱藏。如果否就表示滑鼠真的移出了資訊列(div),那麼資訊列就要隱藏。
複製代碼 代碼如下:// 首先來擷取觸發onMouseOut事件的元素,IE下通過event的toElement屬性來獲得,firefox下通過event的relatedTarget屬性來獲得。
IE:event.toElement ,Firefox:event.relatedTarget(注意:Firefox下的event須通過在函數調用時傳入,而IE下的event則可以直接通過window.event系統對象來獲得)
// ① 接下來就是判斷擷取的元素是否是主體div的子項目(IE下可以通過元素的obj.contains(element)方法來判斷,但Firefox下沒有這個方法,所以需要給firefox定義元素的obj.contains()方法)。
代碼如下:
if(typeof(HTMLElement)!="undefined") // 給firefox定義contains()方法,IE已經系統內建有這個方法了
{
HTMLElement.prototype.contains=function(obj) {
while(obj!=null&&typeof(obj.tagName)!="undefind") { // 通過迴圈對比來判斷是不是obj的父元素
if(obj==this) { return true; }
obj=obj.parentNode;
}
return false;
};
}
// ② 擷取和判斷搞定後,我們就可以通過判斷IE和Firefox來針對處理了,通過navigator.userAgent來判斷瀏覽器類型:
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE";
}
if(navigator.userAgent.indexOf("Firefox")>0){
return "Firefox";
}
// ③ 到此為止所有要解決的問題都得到瞭解決,當觸發onMouseOut事件時,我們將針對不同的瀏覽器先擷取滑鼠到達的元素,然後通過判斷該元素是否在資訊列(div)內,如果元素是子項目,那麼不執行onMouseOut事件,反之則執行事件,隱藏資訊列,完成後的代碼如下:
function hideMsgBox(theEvent){ //theEvent用來傳入事件,Firefox的方式
if (theEvent){
var browser=navigator.userAgent; //取得瀏覽器屬性
if (browser.indexOf("Firefox")>0){ //如果是Firefox
if (document.getElementById('MsgBox').contains(theEvent.relatedTarget)) {//如果是子項目
return; //結束函數
}
}
if (browser.indexOf("MSIE")>0){ //如果是IE
if (document.getElementById('MsgBox').contains(event.toElement)) { //如果是子項目
return; //結束函數
}
}
}
/*要執行的操作(如:隱藏)*/
document.getElementById('MsgBox').style.display='none' ;
……
}
// ④ 在資訊列(Div)上設定onMouseOut=hideMsgBox(event)來調用。
另外,通過設定window.event.cancelBubble = true (IE) ,event.stopPropagation() event.preventDefault() (Firefox) 也可以解決問題,但是需要遍曆所有子項目,影響效率,所以還是在觸發onMouseOut事件時再進行上述判斷分別處理比較合適。