文章目錄
問題:
我正在做一個動態菜單,也就是WEB頁上有一個圖片,當把滑鼠移動到圖片上時,緊挨著圖片的下邊會有一個列表框,這個列表框我是用一個絕對位置的DIV來做的。現在,我想實現當滑鼠移動到圖片上時,列表框出現,當滑鼠從圖片移動到列表框上時,列表框不會消失。但是當滑鼠既不在圖片上也不再列表框上時,列表框消失。。代碼如下:
這是圖片和列表框的HTML:<img src="images/newtopic.gif" mce_src="images/newtopic.gif" alt="" id="imgNewTopic" onmouseover="showNewOptic(this)" onmouseout="relayTime1(event)" /><br /><div id="newTopicTip" onmouseout="relayTime2(event)" ></p><p>
以下是他們的CSS
#imgNewTopic<br />{<br /> float:right;<br />}<br />#newTopicTip<br />{<br /> width:120px;<br /> height:132px;<br /> position:absolute;<br /> border:1px solid #CAD9EA;<br /> clear:right;<br /> display:none;<br /> background-color:#FFFFFF;<br />}</p><p>
下面是寫的JS
//滑鼠移動到發表文章圖片上時顯示DIV<br />function showNewOptic(oImg)<br />{<br /> var oDiv=document.getElementById("newTopicTip");<br /> oDiv.style.display="block";<br /> oDiv.style.left=oImg.offsetLeft-oDiv.offsetWidth+oImg.offsetWidth;<br /> oDiv.style.top=oImg.offsetHeight+oDiv.offsetHeight+oImg.offsetHeight;<br />}<br />//滑鼠移出映像時DIV消失<br />function hideNewOptic()<br />{<br /> var oDiv=document.getElementById("newTopicTip")<br /> oDiv.style.display="none";</p><p>}<br />//DIV延遲一秒後消失<br />function relayTime1(oEvent)<br />{<br /> if(oEvent.toElement.id=="newTopicTip")<br /> {<br />// alert("aa");<br /> return;<br /> }<br /> else<br /> {<br />// alert("img");<br /> setTimeout(hideNewOptic,1000);<br /> }<br />}<br />function relayTime2(oEvent)<br />{<br /> if(oEvent.toElement.id=="imgNewTopic")<br /> {<br />// alert("aa");<br /> return;<br /> }<br /> else<br /> {<br />// alert("div");<br /> setTimeout(hideNewOptic,1000);<br /> }<br />}</p><p>
現在出現問題了,當我把滑鼠移動到圖片上時,DIV列表框出現,這時,他們是緊挨著的,DIV子圖片的正下方。。然而當我把滑鼠從圖片移動到DIV列表框中時。。卻總是會執行DIV的onmouseout事件,不知道是什麼原因,這樣就導致把滑鼠從圖片移動到DIV上後DIV還是會消失。。忘高手解惑~~
解答:
話說有一個DIV元素,其內部有一個IMG元素和SPAN元素,不用理會這兩個內部元素怎麼布局,這不是我要討論的重點。
為了實現一些特殊的效果,我需要利用TD的onmouseover和onmouseout事件,測試時就會發現如下的狀況:
當滑鼠移入DIV內部時,onmouseover事件被觸發;接著再滑鼠移動到DIV內部的IMG或者SPAN元素之上,我們肯定不會認為這時滑鼠已經移到了DIV的外邊,但奇怪的是onmouseout事件觸發了,而且緊接著onmouseover事件也馬上被觸發了。
這可不是我想要的,那麼怎麼來“屏蔽”內部元素給外層元素帶來的Javascript事件幹擾呢?
這裡列舉兩種方法:
一. setTimeout
因為在滑鼠移動到內部元素之上而觸發了外層元素的onmouseout事件後,外層元素的onmouseover也會馬上觸發,所以我們只需要把外層元素的onmouseout事件需要執行的動作延遲很短的一段時間來運行,然後在onmouseover事件中再執行clearTimeout方法,這樣就可以避免內部元素引起的事件幹擾。
這是個很巧妙的的方法,因為當onmouseout觸發後,實質性的方法並沒有馬上執行,而是要等待一小段時間。如果在這段時間裡馬上又觸發了onmouseover事件,那麼基本上就可以肯定onmouseout事件的觸發是因為內部元素的幹擾了,所以在onmouseover事件中使用clearTimeout來阻止延時的方法執行。
二.contains
在onmouseover時先進行如下判斷,結果為true時再執行方法體:
if(!this.contains(event.fromElement)){MouseOverFunc()}
在onmouseout時先進行如下判斷,結果為true時再執行方法體:
if(!this.contains(event.toElement)){MouseOutFunc()}
下面來解釋一下上面兩行代碼的含義:
在IE中,所有的HTML元素都有一個contains方法,它的作用是判斷當前元素內部是否包含指定的元素。我們利用這個方法來判斷外層元素的事件是不是因為內部元素而被觸發,如果內部元素導致了不需要的事件被觸發,那我們就忽略這個事件。
event.fromElement指向觸發onmouseover和onmouseout事件時滑鼠離開的元素;event.toElement指向觸發onmouseover和onmouseout事件時滑鼠進入的元素。
那麼上面兩行代碼的含義就分別是:
○ 當觸發onmouseover事件時,判斷滑鼠離開的元素是否是當前元素的內部元素,如果是,忽略此事件;
○ 當觸發onmouseout事件時,判斷滑鼠進入的元素是否是當前元素的內部元素,如果是,忽略此事件;
這樣,內部元素就不會干擾外層元素的onmouseover和onmouseout事件了。
但問題又來了,非IE的瀏覽器並不支援contains函數,不過既然我們已經知道了contains函數的作用,就可以自行添加如下的代碼來為非IE瀏覽器增加contains支援:
if(typeof(HTMLElement) != "undefined")<br />{<br />HTMLElement.prototype.contains = function(obj)<br />{<br /> while(obj != null && typeof(obj.tagName) != "undefind")<br /> {<br />if(obj == this)<br />Return true;<br />Obj = obj.parentNode;<br />}<br />return false;<br />};<br />}</p><p>
就上面遇到的問題而言,不能用第一種方法,因為我在DIV的onmouseout事件中要條用event對象,而如果用延遲函數setTimeout,將訪問不到event對象。因此本採用第二種解決方案。
具體代碼如下:
HTML:
<img src="images/newtopic.gif" mce_src="images/newtopic.gif" alt="" id="imgNewTopic" onmousemove="showNewOptic(this)" onmouseover="showNewOptic(this)" onmouseout="relayTime1(event)" /><br /><div id="newTopicTip" onmouseout="relayonmouseout(this)" ><br /><p class="pHeader"><a href="#" mce_href="#">發新話題</a></p><br /><hr /><br /><p><a href="#" mce_href="#">發布投票</a></p><br /><hr /><br /><p><a href="#" mce_href="#">發布懸賞</a></p><br /><hr /><br /><p><a href="#" mce_href="#">發行活動</a></p><br /></div>
CSS:
#imgNewTopic<br />{<br />float:right;<br />}<br />#newTopicTip<br />{<br />width:120px;<br />height:132px;<br />position:absolute;<br />border:1px solid #CAD9EA;<br />clear:right;<br />display:none;<br />background-color:#FFFFFF;<br />text-align:center;<br />font-size:13px;<br />}<br />#newTopicTip hr<br />{<br />margin-left:10px;<br />margin-right:10px;<br />margin-top:8px;<br />color:#E8E8E8;<br />}</p><p>#newTopicTip p<br />{<br />margin-top:8px;<br />}<br />#newTopicTip .pHeader<br />{<br />margin-top:18px;<br />}<br />#newTopicTip a:link<br />{<br />color:#000000;<br />text-decoration:none;<br />}<br />#newTopicTip a:hover<br />{<br />color:#003399;<br />}<br />#newTopicTip a:visited<br />{<br />text-decoration:none;<br />}
JS:
//滑鼠移動到發表文章圖片上時顯示DIV<br />function showNewOptic(oImg)<br />{<br /> var oDiv=document.getElementById("newTopicTip");<br /> oDiv.style.display="block";<br /> oDiv.style.left=oImg.offsetLeft-oDiv.offsetWidth+oImg.offsetWidth;<br /> oDiv.style.top=oImg.offsetHeight+oDiv.offsetHeight+oImg.offsetHeight;<br />}<br />//滑鼠移出映像時DIV消失<br />function hideNewOptic()<br />{<br /> var oDiv=document.getElementById("newTopicTip")<br /> oDiv.style.display="none";</p><p>}<br />//DIV延遲一秒後消失<br />function relayTime1(oEvent)<br />{<br /> if(oEvent.toElement.id=="newTopicTip")<br /> {<br />// alert("aa");<br /> return;<br /> }<br /> else<br /> {<br /> alert(oEvent.toElement.id);<br /> setTimeout(hideNewOptic,1000);<br /> }<br />}<br />function relayonmouseout(oDiv)<br />{<br />// inervalID=setTimeout(relayTime2,1000);<br /> if(!oDiv.contains(event.toElement))<br /> {<br /> if(event.toElement.id=="imgNewTopic")<br /> {<br /> return;<br /> }<br /> else<br /> {<br />// alert("div");<br /> setTimeout(hideNewOptic,1000);<br /> }<br /> }<br />}
在此,此問題得到解決~
本文的兩個解決辦法轉載CSDN部落格:http://blog.csdn.net/sallay/archive/2008/11/12/3280170.aspx,在此感謝~