事件代理,又称之为事件委托,是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列表项都绑定一个函数,那对内存的消耗是非常大的。
每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。