場景:1 1 <div class="div1"> 2 click me div1 3 <div class="div2">click me div2</div> 4 </div> 5 6 $(".div2").on('click',function(){ 7 alert($(this).attr( ...
場景:1
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <div class="div1"> 2 click me div1 3 <div class="div2">click me div2</div> 4 </div> 5 6 $(".div2").on('click',function(){ 7 alert($(this).attr('class')) 8 }) 9 10 $(".div1").on('click',function(){ 11 alert($(this).attr('class')) 12 })View Code
問題1.如果點擊click me div2 會顯示什麼?
a) div2
b) div1
c) 先div1 後div2
d) 先div2 後div1
如果用文字來描述這個問題大概的意思是“如果一個元素和它的父元素或者祖先元素綁定了相同的事件,哪一個事件處理函數會先執行?” 答案是根據瀏覽器。沒錯。在IE下會優先執行div2,在Netscape下會先執行div1。而在Mozilla、opera7下結合了前兩者。
為什麼不同瀏覽器之間會有這種差異?
IE認為如果點擊div2,當然要先觸發綁定在div2上事件處理函數,之後再將點擊事件向上傳遞觸發綁定在div1上的事件處理函數。
事件冒泡過程:
/ \ ---------------| |----------------- | div1 | | | | -----------| |----------- | | |div2 | | | | | ------------------------- | | 事件冒泡 | -----------------------------------
Netcape認為因為div2在div1的內部,點擊div2後,點擊事件應該從div1傳遞,先觸發div1上的事件處理函數,隨後點擊事件傳遞到div2上的事件處理函數。
事件捕獲過程:
| | ---------------| |----------------- | div1 | | | | -----------| |----------- | | |div2 \ / | | | ------------------------- | | 事件捕獲 | -----------------------------------
針對這兩種情況,W3C在定義dom 事件模型的時候,採取了一個折中的方法。在W3C事件模型中,事件的傳播順序應該從事件捕獲階段為始到事件冒泡階段結束為終。
| | / \ -----------------| |--| |----------------- | div1 | | | | | | -------------| |--| |----------- | | |div2 \ / | | | | | -------------------------------- | | W3C 事件模型 | ------------------------------------------
那麼問題來了,作為開發人員如何在這種相對比較複雜的環境下來限制事件的傳播順序,從而實現事件綁定的預期效果。
原生js實現方式
element.addEventListener("事件類型",“事件處理函數”,“事件順序”)
事件順序=true
事件處理函數在捕獲階段執行
事件順序 =false
事件處理函數在冒泡階段執行
事件委托
什麼是事件委托?利用事件冒泡或者事件捕獲原理,如果點擊div1,div1自身不處理事件,而是將處理任務委托給父級元素或者祖先元素甚至根節點元素來處理。
運行:https://jsfiddle.net/Mr_do/22wtxxj5/7/
1 <div id="divItem"> 2 3 <div class="div1"> 4 div1 5 </div> 6 7 <div class="div2"> 8 div2 9 </div> 10 11 <div class="div3"> 12 div3 13 </div> 14 15 </div> 16 17 18 19 $("#divItem").delegate('div','click',function(e){ 20 alert($(this).attr('class')) 21 })
事件委托好處在於:
1.對於多個相同的事件,可以將任務委托給同一個函數來處理。
2.提高的web應用的性能,減少占用記憶體
3.結藕js和dom結構的關聯,改變dom結構無需改變js處理函數
參考內容
事件執行順序 :http://www.quirksmode.org/js/events_order.html
事件註冊原理:http://www.quirksmode.org/js/events_advanced.html
W3C DOM Object Model :https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/
事件冒泡與事件捕獲的區別:http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing
事件冒泡與捕獲詳解:http://javascript.info/tutorial/bubbling-and-capturing
DOM Object Model Event :https://www.w3.org/TR/DOM-Level-2-Events/events.html
DOM 事件架構 :http://www.ituring.com.cn/article/428
DOM 事件模型 :http://www.ituring.com.cn/article/420
Jquery 優化事件委托 :http://www.ituring.com.cn/article/467