在開始之前我們先來熟悉一下HTML DOM addEventListener()方法,該方法用於向指定元素添加事件句柄。語法說明如下圖所示:
主要想強調一下第三個參數useCapture,默認值為false表示事件冒泡,為true時表示事件捕獲。
也就是說可以將事件分成事件捕獲和事件冒泡兩種機制。
1、事件捕獲
當一個事件觸發后,從Window對象觸發,不斷經過下級節點,直到目標節點。在事件到達目標節點之前的過程就是捕獲階段。所有經過的節點,都會觸發對應的事件。
2、事件冒泡
當事件到達目標節點后,會沿着捕獲階段的路線原路返回。同樣,所有經過的節點,都會觸發對應的事件。
下面通過一個例子來說明一下:
運行后如下圖:
在父子DIV上我們都添加了點擊事件,當我們點擊div1時,在瀏覽器控制台上會打印出,
說明兩個事件都被觸發了,打印出的順序為div1、div,因為父節點事件的第三個參數默認為false事件冒泡,事件會從目標節點向上返。
如果我們把第三個參數改為true,
控制台打印出的信息會變成,
因為此時采用了事件捕獲的機制,事件會按照從上到下直到目標節點的順序觸發。
事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。借用網上講解事件委托很通用的一個例子來描述一下事件委托的原理:
有三個同事預計會在周一收到快遞。為簽收快遞,有兩種辦法:一是三個人在公司門口等快遞;二是委托給前台MM代為簽收。現實當中,我們大都采用委托的方案(公司也不會容忍那么多員工站在門口就為了等快遞)。前台MM收到快遞后,她會判斷收件人是誰,然后按照收件人的要求簽收,甚至代為付款。這種方案還有一個優勢,那就是即使公司里來了新員工(不管多少),前台MM也會在收到寄給新員工的快遞后核實並代為簽收。
接下來通過一個例子來說明事件委托的應用,請看下面的ul列表,
假如我們想要在所有的li標簽上添加點擊事件,可能我們會想到通過遍歷所有li節點來添加,
這樣做當然可以達到我們的目的,但這樣相當於添加了多個點擊事件,事件處理程序的數量將直接關系到頁面的整體性能,因為添加事件需要不斷的與DOM節點進行交互,導致瀏覽器引擎對頁面不斷的渲染與重繪。
如果使用事件委托的方式,我們只需要在ul標簽上添加一次點擊事件,所有li標簽的點擊通過事件冒泡的方式觸發,
只需要添加一次事件,大大減少了與DOM的交互次數,提升了性能。后面無論我們在ul下面新增加多少個li標簽,都同樣具有點擊事件功能。