javascript
JS事件的捕获和冒泡阶段
JS事件的捕獲和冒泡階段
這里介紹兩個事件模型:IE事件模型與DOM事件模型
以上的HTML代碼在IE內核下,事件是這樣傳播的:
1、Button#child;
2、div#ancestor;
3、Body;
4、Document
DOM標準的瀏覽器事件是:捕獲事件和冒泡事件。
捕獲事件過程:
1、Window
2、Document
3、Body
4、Div#ancestor
5、Button#child
冒泡事件過程:
6、Div#ancestor
7、Body
8、Document
9、Window
當開發者在一個元素上注冊了事件后,這個事件的響應順序是從window(最頂層)開始一級一級的向下傳播,然后到了該元素后事件捕獲過程結束,事件開如冒泡,一級一級向父層元素冒泡(請注意第6步)。
當然,開發者可以很輕松的決定DOM標準的瀏覽器中的事件需要在哪個傳播過程觸發。
事件的注冊機制
DOM標準的瀏覽器事件注冊方法是通過addEventListener方法注冊,而IE內核的瀏覽器則是通過attachEvent方法注冊。
addEventListener
addEventListener方法帶有三個參數,分別是:eventType、handler、useCapture。
a. eventType不帶有on字符串;
b. handler參數是一個事件句柄,這個函數或方法帶有一個事件對象參數;
c. useCapture參數決定了事件句柄觸發在哪種事件傳播階段,如果useCapture為true則為捕獲階段,反之則為冒泡階段。
輸出結果:
"button" "div"當用戶在這個DIV元素上點擊時,事件的執行順序是childHandler、ancestorHandler。
原因:按鈕的事件是在捕獲階段觸發的,也就是從上到下,而DIV的事件是注冊在冒泡階段,也就是點擊了這個按鈕開始從這個按鈕的位置往上冒泡。
其中useCapture我們設置了true,我們選擇在捕獲階段處理該handler。
其中useCapture我們設置了false,我們選擇在冒泡階段處理該handler。
我們來看一下事件的流程:
原因:按鈕的事件是在捕獲階段觸發的,也就是從上到下的順序,而DIV的事件是注冊在冒泡階段,也就是在點擊了這個按鈕button之后,從這個位置往上冒泡。
阻止事件的冒泡:
DOM事件對象提供了stopPropagation方法用于阻止事件流。
var ancestorHandler = function (e){ //...... }, childHandler = function (e){ e.stopPropagation(); //...... };以上代碼在childHandler函數中添加了e.stopPropagation()代碼片段,它將阻止事件流,事件流包括捕獲階段及冒泡階段的事件流。
再修改上面的代碼如下:
let ancestorHandler = function (e){ console.log("div"); } let childHandler = function (e){ console.log("button"); }; document.querySelector('#ancestor').addEventListener('click',ancestorHandler,true);//注意第三個參數 document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三個參數輸出結果:
// 點擊child "div" "button" // 點擊child2 "div"分析一下上面的代碼:
點擊child按鈕
1.當用戶點擊div內的child按鈕元素時,將會依次觸發ancestorHandler、childHandler函數
2.原因是我們將div#ancestor的事件注冊到捕獲階段了,也就是從上到下。
3.用戶點擊div區域,僅僅先觸發了ancestorHandler函數,因為事件流被阻止了
4.處理完ancestorHandler事件之后,再捕獲到child點擊事件,然后執行childHandler函數
點擊child2按鈕
1.當用戶點擊child按鈕時,會觸發點擊div內的元素觸發后的handler,也就是ancestorHandler函數
2.然后輸出div
removeEventListener
刪除監聽事件處理函數的方法,主要是針對移除 addEventListener() 方法添加的監聽事件。
removeEventListener同樣帶有三個參數,分別是:eventType、handler、useCapture,和addEventListener是同樣的。
// 向 <div> 元素添加事件句柄 document.getElementById("myDIV").addEventListener("mousemove", myFunction, false);// 移除 <div> 元素的事件句柄 document.getElementById("myDIV").removeEventListener("mousemove", myFunction, false);示例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vincent</title> <style> #myDIV {background-color: coral;border: 1px solid;padding: 50px;color: white; } </style> </head> <body><div id="myDIV"> div 元素添加了 onmousemove 事件句柄,在你移動鼠標時會顯示隨機數。<p>點擊按鈕移除 DIV 的事件句柄。</p><button onclick="removeHandler()" id="myBtn">點我</button> </div> <p id="demo"></p> <script> document.getElementById("myDIV").addEventListener("mousemove", myFunction); function myFunction() {document.getElementById("demo").innerHTML = Math.random(); } function removeHandler() {document.getElementById("myDIV").removeEventListener("mousemove", myFunction); } </script></body> </html> 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的JS事件的捕获和冒泡阶段的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ngOnInit与constructor
- 下一篇: mall整合SpringBoot+MyB