Javascript中onmouseout与onmouseleave
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
在IE下解決問題很簡單,用onMouseEnter、onMouseLeave來代替onMouseOver、onMouseOut就行了,他們的作用基本相同,前者不會發(fā)生冒泡。但是firefox下沒有這兩個事件,如果用 jQuery的event事件,只要bind mouseleave和mouseenter即可。如果是純js實(shí)現(xiàn),只能這么做:
?
通過判斷觸發(fā)onMouseOut事件后鼠標(biāo)到達(dá)的元素是不是包含在父元素(信息欄Div)內(nèi),如果是就表示鼠標(biāo)還在信息欄上,則不隱藏,如果否就表示鼠標(biāo)真的移出了信息欄,那么信息欄隱藏,思路有了,那么就一步步來解決問題
?
首先來獲取觸發(fā)onMouseOut事件的元素,IE下event的屬性toElement來獲得,在firefox下變成了relatedTarget(很是折騰!)
IE:event.toElement??? Firefox:event.relatedTarget(注意Firefox下event須要調(diào)用函數(shù)時傳入)
?
接下來就是判斷獲取的元素是否是子元素,IE下通過元素的contains(Element)方法可以判斷,同樣的firefox下沒有這個方法!!,不過可以給firefox下的元素定義contains()方法來解決問題,代碼如下:
?
if(typeof(HTMLElement)!="undefined")??? //給firefox定義contains()方法,ie下不起作用
{??
????? HTMLElement.prototype.contains=function(obj)??
????? {??
????????? while(obj!=null&&typeof(obj.tagName)!="undefind"){ //通過循環(huán)對比來判斷是不是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";
?? }
到此為止所有要解決的問題都得到了解決,當(dāng)觸發(fā)onMouseOut事件時我們針對不同的瀏覽器先獲取鼠標(biāo)到達(dá)的元素,然后通過判斷該元素是否在信息欄(div)內(nèi),如果元素是子元素,那么不執(zhí)行onMouseOut事件,反之則執(zhí)行事件,隱藏信息欄,完成后的代碼如下:
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;?? //結(jié)束函式
???????????????????????? }
??????????????? }
????????????????? if (browser.indexOf("MSIE")>0){ //如果是IE
?????????????????????????? if (document.getElementById('MsgBox').contains(event.toElement)) { //如果是子元素
???????????????????????????????? return; //結(jié)束函式
??????????????????????????? }
????????????????? }
???????????? }
??????????? /*要執(zhí)行的操作*/
}
在信息欄(Div)上設(shè)置onMouseOut=hideMsgBox(event)來調(diào)用,解決冒泡問題。
通過設(shè)置
window.event.cancelBubble = true (IE) event.stopPropagation() event.preventDefault() (Firefox)
也可以解決問題,但是需要遍歷所有子元素,影響效率,所以還是在觸發(fā)onMouseOut事件時再進(jìn)行上述判斷分別處理比較合適。
?
================其他方法===========================
?
方案一:
?
希望實(shí)現(xiàn) 當(dāng)鼠標(biāo)離開一個DIV的時候觸發(fā)一個事件處理函數(shù) 于是用onmouseout 結(jié)果卻發(fā)現(xiàn)它的觸發(fā)是不是也太敏感了 原因現(xiàn)在也沒有弄清楚 IE下好像是因?yàn)閰^(qū)分mouseout時的fromElement還是toElement ,IE 5.5以上的onmouseleave事件就比較好用 偏FF又不支持這個事件 只有自己想辦法手工判斷了。
<SCRIPT>
/***
?* 參數(shù)e 是對象傳遞的觸發(fā)事件 FF下想訪問event對象必須傳遞event參數(shù)
* 參數(shù)o 是目標(biāo)DIV對象
*/??
function fun(e,o) {
???????? /* FF 下判斷鼠標(biāo)是否離開DIV */
???????? if(window.navigator.userAgent.indexOf("Firefox")>=1) {
???????????? var x = e.clientX + document.body.scrollLeft;
???????????? var y = e.clientY + document.body.scrollTop ;
???????????? var left = o.offsetLeft;
???????????? var top = o.offsetTop;
???????????? var w = o.offsetWidth;
???????????? var h = o.offsetHeight;
????????????
???????????? if(y < top || y > (h + top) || x > left + w || x<left ) {
???????????????? alert("mouseout");
???????????? }
???????? }
?
??????? /* IE */
???????? if(o.contains(event.toElement ) == false??? )
?alert("mouseout");
????????
???? }
< /SCRIPT>
?
< DIV οnmοuseοut=fun(event,this)>content</DIV>
需要注意 在取鼠標(biāo)的值的時候 一定要加上滾動條已經(jīng)拖動過的內(nèi)容e.clientY + document.body.scrollTop 如果只是e.clientY得到是個錯誤的值 當(dāng)然如果高寬都很小 是看不出來問題。 取一個對象的高和寬 也可以使用 clientHeight clientWidth 屬性 以后遇到FF IE不兼容的時候要多看看FF的開發(fā)手冊http://developer.mozilla.org/en/docs/DOM:element.offsetLeft
??
方案二:(與一相似)
?
js的onmouseout有很奇怪的一個問題。例如
?
<div οnmοuseοut="alert(123)">
?
< a href="#">test</a>
?
< /div>
?
我們預(yù)期只有當(dāng)鼠標(biāo)從div中移開的時候才會觸發(fā)onmouseout事件,可是,事實(shí)上,當(dāng)我們移到div中的元素時,例如本例中的a標(biāo)簽時,就 會觸發(fā)onmousout事件。也就是說,移到對象的子對象上,也算onmouseout了。這往往會讓我們預(yù)期的效果達(dá)不到。今天的工作就遇到了這個問 題。在blueidea上搜了一下,找了解決辦法。兼容IE和FF。
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>test</title>
< /head>
?
< body>
< script type="text/javascript">
function test(obj, e) {
if (e.currentTarget) {
?if (e.relatedTarget != obj) {
if (obj != e.relatedTarget.parentNode) {
alert(1);
?}
}
} else {
if (e.toElement != obj) {
?if (obj != e.toElement.parentNode) {
alert(1);
}
}
?}
}
?< /script>
< div οnmοuseοut="test(this, event)" style="width:100px;height:100px;border:1px #666 solid">
?< span style="margin:5px;width:100%;height:100%;border:1px #ff0000 solid">faddsf</span>
< /div>
< /body>
?< /html>
?
今天發(fā)現(xiàn)JQ中關(guān)于這個問題,已經(jīng)有了一個好的解決辦法了.呵呵,jquery中定義了一種事件叫做"mouseleave",用這個事件做事件句柄的話,就可以解決這個問題了.越來越發(fā)現(xiàn)jquery是個好東西了.
?
方案三:
??
jQuery V1.2.2推薦用bind("mouseleave",function(){})來代替以前的mouseover方法用bind("mouseenter",function(){})來代替mouseout,同樣也針對以前的hover方法,要看詳細(xì)的說明點(diǎn)這個地址:http://docs.jquery.com/Release:jQuery_1.2.2
?
$(document).ready(function() {
??? $("#a1").bind("mouseleave", function(){
??? $('<div style="color:red;">out</div>')
??? .insertAfter($(this));
});
});
?
轉(zhuǎn)載于:https://my.oschina.net/junn/blog/112851
總結(jié)
以上是生活随笔為你收集整理的Javascript中onmouseout与onmouseleave的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP框架 Phalcon 1.0.0
- 下一篇: unistd.h 中int access