在介紹JS中事件委派之前先來看看一個簡單的需求:為每一個超鏈接綁定一個單擊響應函數並在控制台打印一句話,內容是:” a 標簽的單擊響應函數“。下面是這個需求的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script> // 需求:為每一個超鏈接綁定一個單機響應函數 window.onload = function() { // 獲取頁面中所有的 a 標簽 var allA = document.getElementsByTagName('a'); for(var i = 0; i < allA.length; i++) { allA[i].onclick = function() { console.log('我是 a 的單擊響應函數'); } } } </script> </head> <body> <ul id="ul"> <li><a href="javascript:;">超鏈接1</a></li> <li><a href="javascript:;">超鏈接2</a></li> <li><a href="javascript:;">超鏈接3</a></li> </ul> </body> </html>
在瀏覽器中打開上部分代碼,點擊相應的超鏈接, 都可以在控制台打印“我是 a 的單擊響應函數”。感覺好像是夠用了,哈哈哈哈,其實還沒完。
在此基礎上升級,現在要做的是點擊添加按鈕追加一個 ul 的子元素 li。被新添加進去的 li 也能觸發循環綁定的事件方法,下面是具體代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script> window.onload = function () { var ul = document.getElementById('ul'); var allA = document.getElementsByTagName('a'); var btn = document.getElementById('btn'); btn.onclick = function () { // 創建一個li標簽 var li = document.createElement('li'); li.innerHTML = '<a href="javascript:;" class="link">新添加的超鏈接</a>'; ul.appendChild(li); } for (var i = 0; i < allA.length; i++) { allA[i].onclick = function () { console.log('我是 a 的單擊響應函數'); } } } </script> </head> <body> <button id="btn">點擊添加</button> <ul id="ul"> <li><a href="javascript:;">超鏈接1</a></li> <li><a href="javascript:;">超鏈接2</a></li> <li><a href="javascript:;">超鏈接3</a></li> </ul> </body> </html>
在瀏覽器打開,點擊添加一個子元素,可以看到之前循環綁定事件的函數不管用了,被新添加的元素不會觸發 onclick 事件方法,不能在控制台打印 “我是a標簽的響應函數 ”,這里就涉及到事件委派了,先來看看事件委派的原理。
事件委派:將事件統一綁定給元素共同的祖先元素(后代元素事件觸發時,通過冒泡,通過祖先元素的響應函數來處理事件),這樣可以只綁定一次,即可應用到多個元素上。事件的委派利用了冒泡,通過委派可以減少事件綁定的次數,提高程序的性能event中的target表示的觸發事件的對象 ,使用它對觸發事件的元素進行判斷。
我現在的需求是:只需要綁定一次事件並可以應用到多個元素上,即使元素是后添加的,也能觸發這個事件方法。具體代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!-- 需求:為每一個li綁定一個函數 --> <button id="btn">點擊添加超鏈接</button> <ul id="ul" style="background-color: pink"> <li><a href="javascript:;" class="link">超鏈接1</a></li> <li><a href="javascript:;" class="link">超鏈接2</a></li> <li><a href="javascript:;" class="link">超鏈接3</a></li> </ul> <script> window.onload = function () { var ul = document.getElementById('ul'); var btn = document.getElementById('btn'); btn.onclick = function () { // 創建一個li標簽 var li = document.createElement('li'); li.innerHTML = '<a href="javascript:;" class="link">新添加的超鏈接</a>'; ul.appendChild(li); } var allA = document.getElementsByTagName('a'); ul.onclick = function (event) { if (event.target.className == 'link') { alert(`我是a`); } } } </script> </body> </html>
target 返回目標元素,表示觸發事件的對象。