一、寫在前頭
接到某廠**問什麼是事件**的時候,一開始說addeventlistener,然後他說直接繫結新的元素不會報dom不存在的錯誤嗎?然後我就混亂了,我印象中這個方法是可以繫結新節點的。後面才知道,原來他要考察的是事件委託(**)的原理,他指的是未來還不清楚會建立多少個節點,所以沒辦法實現給他們註冊事件。
二、事件委託(事件**)的作用?
為了方便理解,我先把事件委託的作用寫一下。
支援為同乙個dom元素註冊多個同型別事件
可將事件分成事件捕獲和事件冒泡機制
例子解析:
用以往註冊事件的方法,如果存在多個事件,後註冊的事件會覆蓋先註冊的事件可以看到第二個點選註冊事件覆蓋了第乙個註冊事件,只執行了console.log('列印第二次');
用addeventlistener(type,listener,usecapture)實現可以看到兩個註冊事件都成功觸發了。 usecapture是事件委託的關鍵,我們後面詳解
事件捕獲
當乙個事件觸發後,從window物件觸發,不斷經過下級節點,直到目標節點。在事件到達目標節點之前的過程就是捕獲階段。所有經過的節點,都會觸發對應的事件
事件冒泡
當事件到達目標節點後,會沿著捕獲階段的路線原路返回。同樣,所有經過的節點,都會觸發對應的事件
通過例子理解兩個事件機制:
例子:假設有body和body節點下的div1均有繫結了乙個註冊事件.
效果:當為事件捕獲(usecapture:true)時,先執行body的事件,再執行div的事件
當為事件冒泡(usecapture:false)時,先執行div的事件,再執行body的事件
//當usecapture為預設false時,為事件冒泡
window.onload = function())
div1.addeventlistener('click',function())
}//結果:列印div1 列印body
三、事件委託和新增節點繫結事件的關係?//當usecapture為true時,為事件捕獲
window.onload = function(),true)
div1.addeventlistener('click',function())
}//結果:列印body 列印div1
事件委託的優點:
提高效能:每乙個函式都會占用記憶體空間,只需新增乙個事件處理程式**所有事件,所占用的記憶體空間更少。
動態監聽:使用事件委託可以自動繫結動態新增的元素,即新增的節點不需要主動新增也可以一樣具有和其他元素一樣的事件。
例子解析:
雖然沒有給div1和div2新增點選事件,但是無論是點選div1還是div2,都會列印當前節點。因為其父級繫結了點選事件,點選div1後冒泡上去的時候,執行父級的事件。div1
div2
分別點選div1、div2、div3這樣無論後代新增了多少個節點,一樣具有這個點選事件的功能。這乙個就是考察者想要聽到的答案。徹底弄懂JS的事件冒泡和事件捕獲
先上結論 他們是描述事件觸發時序問題的術語。事件捕獲指的是從document到觸發事件的那個節點,即自上而下的去觸發事件。相反的,事件冒泡是自下而上的去觸發事件。繫結事件方法的第三個引數,就是控制事件觸發順序是否為事件捕獲。true,事件捕獲 false,事件冒泡。預設false,即事件冒泡。jqu...
徹底弄懂JS的事件冒泡和事件捕獲
在學校,聽老師講解事件冒泡和事件捕獲機制的時候跟聽天書一樣,只依稀記得ie使用的是事件冒泡,其他瀏覽器則是事件捕獲。當時的我,把它當成ie瀏覽器相容問題,所以沒有深究 ie8以下版本的瀏覽器已基本退出市場 工作至今,雖然多次遇到該類問題,但均未深究,始終一知半解,遇到了全tm靠猜 選a不行就選b唄 ...
轉 徹底弄懂JS的事件冒泡和事件捕獲
在學校,聽老師講解事件冒泡和事件捕獲機制的時候跟聽天書一樣,只依稀記得ie使用的是事件冒泡,其他瀏覽器則是事件捕獲。當時的我,把它當成ie瀏覽器相容問題,所以沒有深究 ie8以下版本的瀏覽器已基本退出市場 工作至今,雖然多次遇到該類問題,但均未深究,始終一知半解,遇到了全tm靠猜 選a不行就選b唄 ...