說到 addEventListener 不得不說到事件流,先說事件流對后面的解釋比較方便。
當一個事件發生時,分為三個階段:
捕獲階段 從根節點開始順序而下,檢測每個節點是否注冊了事件處理程序。如果注冊了事件處理程序,并且 useCapture 為 true,則調用該事件處理程序。(IE 中無此階段。)
目標階段 觸發在目標對象本身注冊的事件處理程序,也稱正常事件派發階段。
冒泡階段 從目標節點到根節點,檢測每個節點是否注冊了事件處理程序,如果注冊了事件處理程序,并且 useCapture 為 false,則調用該事件處理程序。
舉例
1 <div id="div1">
2 <div id="div2">
3 <div id="div3">
4 <div id="div4">
5 </div>
6 </div>
7 </div>
8 </div>
2 <div id="div2">
3 <div id="div3">
4 <div id="div4">
5 </div>
6 </div>
7 </div>
8 </div>
如果在 d3 上點擊鼠標,事件流是這樣的:
捕獲階段 在 div1 處檢測是否有 useCapture 為 true 的事件處理程序,若有,則執行該程序,然后再同樣地處理 div2。
目標階段 在 div3 處,發現 div3 就是鼠標點擊的節點,所以這里為目標階段,若有事件處理程序,則執行該程序,這里不論 useCapture 為 true 還是 false。
冒泡階段 在 div2 處檢測是否有 useCapture 為 false 的事件處理程序,若有,則執行該程序,然后再同樣地處理 div1。
注意,上述捕獲階段和冒泡階段中,實際上 div1 之上還應該有結點,比如有 body,但這里不討論。