一、概念
事件委托也叫事件代理,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
举个简单的例子:
- 比如一个班级的同学的快递同时到了,一种方法就是他们一个个去领,另一种方法就是把这件事情委托给班长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个同学;
- 这样的话,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的班长长就是代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。
事件委托的优点
:
- 可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件。
<ul id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
......
<li>item n</li>
</ul>
// ...... 代表中间还有未知数个 li
- 可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
基本实现
【1】JavaScript原生实现事件委托
HTML代码:
<ul id="ul">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<button id="btn">点我添加一个li</button>
JS代码:
// 事件委托具体实现
var ul = document.getElementById("ul");
ul.onclick = function (event) {
event = event || window.event;
var target = event.target;
// 获取目标元素
if (target.nodeName == 'LI') {
alert(target.innerHTML);
}
}
// 为按钮绑定点击事件
var btn = document.getElementById('btn');
btn.onclick = function () {
var li = document.createElement('li');
// 新增li的内容为ul当前子元素的个数
li.textContent = ul.children.length;
ul.appendChild(li);
}
【2】jQuery事件delegate()实现事件委托
首先举个例子:
如果1个div下面有3个button,点击每个按钮的时候,需要打印出当前按钮的ID。
<div id="app">
<input type="button" id="a" value="1"></input>
<input type="button" id="b" value="2"></input>
<input type="button" id="c" value="3"></input>
</div>
- 方法一:使用JQuery选择器,给每个按钮都绑定自己的事件处理函数。
$("#app :button").click(function(){
alert($(this).attr("id"));
})
- 方法二:利用事件委托机制,只给按钮的父元素绑定事件。
$("#app").delegate(":button","click",function(){
alert($(this).attr("id"));
});
delegate函数使用方式如下:
delegate(selector, [type], [data], fn)
selector
选择器:
代替JQuery中的选择器,用来过滤触发事件的元素。上面的app元素下面有a、b、c这3个按钮,如果点击按钮b的时候,不打印出它的ID。那么可以通过如下代码实现:
$("#app").delegate(":button[id!='b']","click",{},function(){
alert($(this).attr("id"));
});