事件冒泡、事件捕獲、事件委託
阿新 • • 發佈:2021-10-20
首先介紹個方法
element.addEventListener(event, function, useCapture)
addEventListener方法原生的JS方法,用來為一個特定的元素繫結一個事件處理函式。
三個引數分別:
- event: 事件型別
- function: 事件處理函式
- useCapture: 控制事件階段
第三個引數useCapture是boolean型別:
預設是false,表示在事件冒泡的階段呼叫事件處理函式,
如果設定為 true,則表示在事件捕獲的階段呼叫事件處理函式。
事件冒泡
當一個元素接收到事件的時候 會把他接收到的事件傳給自己的父級,一直到window。
即指子元素的事件向父元素傳遞的過程。
例如:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> </head> <body> <div> <p> <button id="b1">點我</button> </p> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> /* 因為監聽函式addEventListener第三個引數預設為false 因此直接使用click、focus等函式,預設就是冒泡事件 */ $('div').click(function () { console.log('我是div標籤'); }); $('p').click(function () { console.log('我是一個p標籤'); }); // $('#b1')[0] JQ原生轉DOM元素 $('#b1')[0].addEventListener('click', function () { console.log('我是那個按鈕!'); }, false) </script> </body> </html>
當點選按鈕後,事件會從子元素(button)一直傳遞到父元素window,結果:
事件捕獲
事件捕獲與事件冒泡相反,事件的傳遞從父元素向下傳遞到子元素。
即指父元素的事件向子元素傳遞的過程。
例如:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>事件捕獲</title> </head> <body> <div> <p> <button id="b1">點我</button> </p> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> // 設定為true代表事件捕獲 $('div')[0].addEventListener('click', function () { console.log('我是div標籤'); }, true); $('p')[0].addEventListener('click', function () { console.log('我是一個p標籤'); }, true); // $('#b1')[0] JQ原生轉DOM元素 $('#b1')[0].addEventListener('click', function () { console.log('我是那個按鈕!'); }, true) </script> </body> </html>
當點選按鈕後,事件會從父元素window一直傳遞到子元素(button),結果:
事件冒泡與事件捕獲的關係
即:事件捕獲先發生,再到事件冒泡
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>事件冒泡與捕獲</title> </head> <body> <div> <p> <button id="b1">點我</button> </p> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> // 事件捕獲 $('div')[0].addEventListener('click', function () { console.log('我是div標籤'); }, true); // 事件冒泡 $('div')[0].addEventListener('click', function () { console.log('我是div標籤'); }, false); $('p')[0].addEventListener('click', function () { console.log('我是一個p標籤'); }, true); $('p')[0].addEventListener('click', function () { console.log('我是一個p標籤'); }, false); $('#b1')[0].addEventListener('click', function () { console.log('我是那個按鈕!'); }, true) $('#b1')[0].addEventListener('click', function () { console.log('我是那個按鈕!'); }, false) </script> </body> </html>
當點選按鈕後,先發生事件捕獲,再發生事件冒泡,結果:
事件委託
事件委託是通過事件冒泡的原理,利用父標籤去捕獲子標籤的事件。
語法: $("table").on("click", "button", function () { // JS程式碼 }) 解釋:給table繫結一個點選事件,但是是通過button觸發的。
注意事項1:
像click、keydown等DOM中定義的事件,我們都可以使用`.on()`方法來繫結事件,但是`hover`這種jQuery中定義的事件就不能用`.on()`方法來綁定了,
也就是說hover()方法不能直接使用事件委託,想使用事件委託的方式繫結hover事件處理函式,可以參照如下程式碼分兩步繫結事件:
$('ul').on('mouseenter', 'li', function() {//繫結滑鼠進入事件 $(this).addClass('hover'); }); $('ul').on('mouseleave', 'li', function() {//繫結滑鼠劃出事件 $(this).removeClass('hover'); });
注意事項2
關於this:誰觸發這個事件,this就指向誰。
例如:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> </head> <body> <div id="div"> <p id="p"> <input type="button" value="點我" id="btn"> </p> </div> <script type="text/javascript"> $("#div").click(function () { //點選按鈕,經過事件冒泡,觸發這個事件 //此時this是代表div的,雖然點選的是那個按鈕 //但是實際上是經過冒泡後,div自己觸發的這個事件,所有this是div console.log(this); }); //任意註釋一個script標籤測試另一個標籤 $("#div").on("click", "#btn", function () { //事件委託,給div綁定了一個事件,點選按鈕觸發這個事件 //此時this是代表按鈕btn的,雖然繫結的事件是div //但是觸發這個事件的是btn,所以this是btn console.log(this); }) </script> </body> </html>