因爲搬去敵臺了,很久沒來博客園,今天無心中翻到有「誤認子弟」的評論,這裏特地作個說明。css
本文中關於事件冒泡和事件捕獲的描述和例子都是OK的,錯就錯在後面用jquery去展現了利用事件冒泡的例子有誤,其實這部分就是「事件委託」,而當時的我並不知道,這一點在我好久以前的評論中糾正過。html
歸根結底,是當時的我對dom事件這個東西沒有一個系統的認識。事件模型、事件流、event對象、事件代理/委託、甚至自定義事件,加起來纔是dom事件的全貌,都理解了才能完全弄懂。本想刪除了事,但抱着尊重歷史的態度(實際上是我不捨得刪,畢竟是個人第一篇博文),特地在標題中標明:不推薦閱讀。jquery
最後,對被「毒害」了的萌新和讀者們表示最真摯的歉意,抱歉!請你們原諒那個當初年幼無知的我!瀏覽器
---------以上爲2019.2.13更新---------------app
在學校,聽老師講解事件冒泡和事件捕獲機制的時候跟聽天書同樣,只依稀記得IE使用的是事件冒泡,其餘瀏覽器則是事件捕獲。當時的我,把它當成IE瀏覽器兼容問題,因此沒有深究(IE8如下版本的瀏覽器已基本退出市場)。工做至今,雖然屢次遇到該類問題,但均未深究,始終只知其一;不知其二,遇到了全TM靠猜(選A不行就選B唄)。今天閒來無事本身作了個demo,算是把這個問題完全搞明白了。dom
先上結論:他們是描述事件觸發時序問題的術語。事件捕獲指的是從document到觸發事件的那個節點,即自上而下的去觸發事件。相反的,事件冒泡是自下而上的去觸發事件。綁定事件方法的第三個參數,就是控制事件觸發順序是否爲事件捕獲。true,事件捕獲;false,事件冒泡。默認false,即事件冒泡。Jquery的e.stopPropagation會阻止冒泡,意思就是到我爲止,個人爹和祖宗的事件就不要觸發了。性能
這是HTML結構this
<div id="parent"> <div id="child" class="child"></div> </div>
如今咱們給它們綁定上事件spa
document.getElementById("parent").addEventListener("click",function(e){ alert("parent事件被觸發,"+this.id); }) document.getElementById("child").addEventListener("click",function(e){ alert("child事件被觸發,"+this.id) })
結果:代理
child事件被觸發,child
parent事件被觸發,parent
結論:先child,而後parent。事件的觸發順序自內向外,這就是事件冒泡。
如今改變第三個參數的值爲true
document.getElementById("parent").addEventListener("click",function(e){ alert("parent事件被觸發,"+e.target.id); },true) document.getElementById("child").addEventListener("click",function(e){ alert("child事件被觸發,"+e.target.id) },true)
結果:
parent事件被觸發,parent
child事件被觸發,child
結論:先parent,而後child。事件觸發順序變動爲自外向內,這就是事件捕獲。
貌似沒什麼卵用,上一個利用事件冒泡的案例,反正我是常常會用到。
<ul> <li>item1</li> <li>item2</li> <li>item3</li> <li>item4</li> <li>item5</li> <li>item6</li> </ul>
需求是這樣的:鼠標放到li上對應的li背景變灰。
利用事件冒泡實現:
$("ul").on("mouseover",function(e){ $(e.target).css("background-color","#ddd").siblings().css("background-color","white"); })
也許有人會說,咱們直接給全部li都綁上事件也能夠啊,一點也不麻煩,只要……
$("li").on("mouseover",function(){ $(this).css("background-color","#ddd").siblings().css("background-color","white"); })
是,這樣也行。並且從代碼簡潔程度上,二者是相若彷彿的。可是,前者少了一個遍歷全部li節點的操做,因此在性能上確定是更優的。
還有就是,若是咱們在綁定事件完成後,頁面又動態的加載了一些元素……
$("<li>item7</li>").appendTo("ul");
這時候,第二種方案,因爲綁定事件的時候item7還不存在,因此爲了效果,咱們還要給它再綁定一次事件。而利用冒泡方案因爲是給ul綁的事件……
高下立判!