本文已参与「新人创作礼」活动,一起开启掘金创作之路。
所谓事件委托就是利用事件冒泡的特性,将本应该注册在子元素上的处理事件注册在父元素上,这样点击子元素时发现其本身没有相应事件就到父元素上寻找。
《javascript 高级程序设计》中定义: 事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
优点:
- 减少 DOM 操作,减少内存占用,提高性能
- 随时可以添加子元素,添加的子元素会自动有相应的处理事件
说是这么说,但是对于新手来讲就会想这样一个问题,例如点击事件,我们如何能够在父元素的点击处理事件中知道点击的到底是哪个子元素呢?这就是是事件委托的关键:Event 对象
每个事件都有一个 Event 对象,Event 对象提供了一个属性叫做 target,可以返回事件的目标节点,即事件源。也就是说target就可以表示当前的事件操作的 DOM。
处理同类事件
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
<script>
window.onload = function() {
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if (target.nodeName.toLowerCase() == "li") {
alert(123);
alert(target.innerHTML);
}
};
};
</script>
处理不同类事件
<div id="box">
<input type="button" id="add" value="添加" />
<input type="button" id="remove" value="删除" />
<input type="button" id="move" value="移动" />
<input type="button" id="select" value="选择" />
</div>
<script>
window.onload = function() {
var oBox = document.getElementById("box");
oBox.onclick = function(ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if (target.nodeName.toLocaleLowerCase() == "input") {
switch (target.id) {
case "add":
alert("添加");
break;
case "remove":
alert("删除");
break;
case "move":
alert("移动");
break;
case "select":
alert("选择");
break;
}
}
};
};
</script>
总结
事件委托的精髓就在于不需要去遍历子节点,只需要给父级元素添加事件就好,其他都是在 js 里执行,从而大大减少 DOM 操作。
适合事件委托的事件:click、mousedown、mouseup、keydown、keyup、keypress
注意:mouseover 和 mouseout 虽然也有事件冒泡,但是因为需要经常计算他们的位置,所处理起来不太容易。对于本身就没有事件冒泡的事件,自然就不能用事件委托了。