在學習javascript中,如果在事件的使用上出現一些反差效果,不良效果,如滑鼠的移入移出時,顯示你所需要的內容, 但就是沒有出現,然而你不斷的檢查代碼,逐個代碼查錯,還在瀏覽器的調試工具中調試都沒有發現錯誤,沒有看到你所 想要的錯誤,那麼這個時候你要判斷一下是不是冒泡事件帶來的不良效果了,不過在 ...
在學習javascript中,如果在事件的使用上出現一些反差效果,不良效果,如滑鼠的移入移出時,顯示你所需要的內容,
但就是沒有出現,然而你不斷的檢查代碼,逐個代碼查錯,還在瀏覽器的調試工具中調試都沒有發現錯誤,沒有看到你所
想要的錯誤,那麼這個時候你要判斷一下是不是冒泡事件帶來的不良效果了,不過在判斷之前,你是不是要知道什麼是冒泡事件呢?
接下來冒泡的解釋:
冒泡就是從里的事件源一級一級向上觸發直到window:
圖:
事件源就是你所觸發事件在位置的元素,而在這個元素觸發了事件,如圖你所觸發的元素是編號為4的物塊,而它就是事件源,
還有事件其實在你沒有編寫前就給每個元素對象自動添加上,就差你給它添加事件函數了,有個事件函數,它的事件才會有東西
執行,不是只是個空有事件,沒有事件函數的事件,這點要搞懂,不是會走進誤區!!!!
上面假設的那個冒泡就是從這個編號4的物塊一層一層向上冒泡,直到window,而它順序:
事件來源對象編號4->上級對象編號3->上上級對象編號2->上上上級對象編號1->body->document->window
註意:這個冒泡只和你的HTML結構有關,不能直觀的看表現出效果,判斷它的某些子元素不會觸發冒泡給上層,只要是在
HTML結構里元素就會向上冒泡給上級。
圖:
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{ width: 100px; height: 100px; } #div1{ background: red; position: relative; } #div2{ position: absolute; top: 150px; background: green; } </style> </head> <body> <div id="div1"> <div id="div2"></div> </div> </body> </html>
從圖可以直觀看一定不知道它們的HTML結構是父子關係,所以會走進誤區,以為這兩個是獨立的塊,不會冒泡到其中一個為父級元素,但從代碼看,這個就是父子關係,所以觸發子級,會冒泡給父級再向上冒泡。
所以這個一定要搞懂。
這就是冒泡;
接下來就是冒泡事件的不良反應,比如你只想觸發某個元素的事件,但它的父級或上上級也被你觸發了,那麼你就要阻止了,
還有就是你的事件加了定時器了,這時你就要註意冒泡的不良反應了,如你想當前元素觸發事件但到後代元素後當前元素又再一次觸發它的事件,然後又調用到定時器,
然後你的效果就向不理想的現象觸發,這是一種不良情況,還有很多,等以後一一自己去體驗,而這些的不良效果,都主要阻止冒泡就可以了。
而阻止冒泡前,你要找到你所要阻止的元素,他不一定是你所需效果的元素的位置,可能是它子級的元素,所以你要先找到這個阻止源,然後才是在這個元素放阻止的
方法,一般阻止使用event.cancelBubble=true;即可,現在的主流瀏覽器都支持,但之前版本的火狐是不支持的,所以如果出現不支持那麼請做相容,event.stopPropagation();
這個是火狐之前版本支持的,當然的現在的版本也支持。
錯誤代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>冒泡</title> <style> #div1{ width: 500px; height: 500px; margin: 0 auto; background: red; } #div2{ width: 300px; height: 300px; margin: 0 auto; background: green; } #div3{ width: 100px; height: 100px; margin: 0 auto; background: #eeeeee; } </style> <script> window.onload=function(){ var oDiv=document.getElementById("div1"); oDiv.onmouseover=function(ev){ ev=ev||event; this.style.background="#000"; } oDiv.onmouseout=function(ev){ timer=setTimeout(function(){ oDiv.style.background="red"; },1000); } } </script> </head> <body> <div id="div1"> <div id="div2"> <div id="div3"></div> </div> </div> </body> </html>
執行這些代碼一定發現問題;
阻止冒泡後修改的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>阻止冒泡</title> <style> #div1{ width: 500px; height: 500px; margin: 0 auto; background: red; } #div2{ width: 300px; height: 300px; margin: 0 auto; background: green; } #div3{ width: 100px; height: 100px; margin: 0 auto; background: #eeeeee; } </style> <script> window.onload=function(){ var oDiv=document.getElementById("div1"); var oDiv1=document.getElementById("div2"); var oDiv2=document.getElementById("div3"); var timer=null; oDiv1.onmouseover=function(){ clearInterval(timer); } oDiv1.onmouseout=function(ev){ ev=ev||event; ev.cancelBubble=true; } oDiv2.onmouseout=function(ev){ ev=ev||event; ev.cancelBubble=true; } oDiv.onmouseover=function(ev){ ev=ev||event; this.style.background="#000"; } oDiv.onmouseout=function(ev){ timer=setTimeout(function(){ oDiv.style.background="red"; },1000); } } </script> </head> <body> <div id="div1"> <div id="div2"> <div id="div3"></div> </div> </div> </body> </html>
之於定時器的是什麼,自己去普及。
OK~大體的說了說。
冒泡有不少好處,事件委托就是其一;
事件委托:
事件委托就是使用父級為子級幹事,它的核心是利用冒泡,還有事件源屬性使用event.srcElement,它需要去相容,還有個屬性是event.target,
相容例子:
var obj=event.srcElement||event.target;
它有個好處是如果你動態的為父級添加子標簽,那些添加的子標簽都可以使用這些事件方法,也能觸發這些事件,就像動態的添加函數一樣,使它們都有自己的事件。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>無標題文檔</title> <style> #m1{ width:200px; background:#0F6; overflow:hidden; margin:60px auto; } li{ width:100px; height:50px; margin:50px auto 50px; text-align:center; line-height:50px; border:2px solid #999; cursor:pointer; } </style> </head> <ul id="m1"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> <li>666</li> </ul> <input type="button" id="btn" value="添加" /> <script> var num=6; var btn=document.getElementById("btn"); var m1=document.getElementById("m1"); m1.onmouseover=function(){ var e=event||window.event; var obj=e.srcElement||e.target; if(obj.nodeName.toLowerCase()=="li"){ obj.style.background="#ff0"; } }; m1.onmouseout=function(){ var e=event||window.event; var obj=e.srcElement||e.target; obj.style.background=""; }; btn.onclick=function(){ num++; var li=document.createElement("li"); li.innerHTML=111*num; m1.appendChild(li); }; </script> <body> </body> </html>
到此為止了。
還有事件捕獲在待定中。。。