事件代理,又稱之爲事件委託,是JS中綁定事件的常用技巧,顧名思義,事件代理就是把原本需要綁定在子元素上的事件委託給父元素,事件代理的原理是冒泡機制。
下面我來舉個例子:
先寫出頁面上的HTML結構
<button id="btn">添加按鈕</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
我們的需求是,點擊button在ul中添加一個li ,並且我們需要實現點擊li的時候讓其背景顏色變成red;
var lis = document.getElementsByTagName("li");
var btn=document.getElementById('btn');
var ulNode=document.getElementsByTagName('ul')[0];
btn.οnclick=function(){
var lis = document.getElementsByTagName("li");
var li=document.createElement('li');
li.innerHTML=lis.length+1;
ulNode.appendChild(li)
}
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
this.style.background = "red";
};
}
粗心的同學很容易寫出上述代碼,但是,後面的通過btn添加的li並不會有事件。
我們未來還不清楚會創建多少個節點,所以沒辦法實現給他們註冊事件。
所以,這裏我們就需要通過事件委託來實現這個需求,把事件委託給父元素。
var lis = document.getElementsByTagName("li");
var btn=document.getElementById('btn');
var ulNode=document.getElementsByTagName('ul')[0];
btn.οnclick=function(){
var lis = document.getElementsByTagName("li");
var li=document.createElement('li');
li.innerHTML=lis.length+1;
ulNode.appendChild(li)
}
ulNode.οnclick=function(e){
if(e.target.tagName=='LI'){
e.target.style.background='red'
}else{
return
}
}
不僅如此,事件委託還有一些性能上的優點,如果給每個li列表項都綁定一個函數,那對內存的消耗是非常大的。
每一個函數都會佔用內存空間,只需添加一個事件處理程序代理所有事件,所佔用的內存空間更少。