一:Hello html
js中事件委託主要是爲了解決兩個問題node
1)在節點比較多的時候循環綁定事件比較佔內存,浪費性能app
2)新追加節點的事件的註冊性能
二:原理分析spa
直接上demo,結尾處有完整代碼。code
1.DOM 結構htm
<ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li> </ul>
2.需求是給每一個li註冊一個綁定事件 fnClick對象
這是傳統方式,獲取li,循環綁定blog
1 for ( var i = 0; i < aLi.length; i++ ) { 2 aLi[i].onclick = fnClick; 3 }
tips: 會遇到的問題是 1.浪費性能 2.新追加節點沒法添加事件 3.寫法醜 -- 如開頭所說 事件
事件委託登場
1 oUl.onclick = function (ev) { 2 var target = ev.target; 3 // 對於元素節點來講 nodeName 和 tagName 是同樣的 4 if (target.tagName.toLowerCase() == 'li') { 5 console.log(target.innerHTML); 6 } 7 };
tips:
1.委託的原理是將事件添加到父節點ul 上,在經過事件對象來找到對應的節點
2.對於元素節點來講,nodeName 和 tagName 是同樣的,獲取到的是標籤的 大寫 名
3.使用事件委託的時候新添加的節點也會有對應的事件
具體見完整代碼(做爲暖男,我特地去掉了行號,方便複製)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件委託</title> <style> li { border: 1px solid #999; margin-bottom: 10px; } </style> </head> <body> <button id="btn">追加節點</button> <ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li> </ul> <script> var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li"); var addBtn = document.getElementById("btn"); var num = 0; var fnClick = function () { console.log(1); }; // 這個是十分醜陋的並且十分浪費性能的解決方式 // for ( var i = 0; i < aLi.length; i++ ) { // aLi[i].onclick = fnClick; // } oUl.onclick = function (ev) { var target = ev.target; // 對於元素節點來講 nodeName 和 tagName 是同樣的 if (target.tagName.toLowerCase() == 'li') { console.log(target.innerHTML); } }; addBtn.onclick = function () { num ++; var newLi = document.createElement("li"); newLi.innerHTML = num * 111111; oUl.appendChild( newLi ); }; </script> </body> </html>