首先灵魂三问:是什么?为什么?怎么做?
事件委托是什么?
要理解事件委托我们先来了解下事件捕捉和事件冒泡:
当一个事件发生在具有父元素的元素上时,现代浏览器运行两个不同的阶段 - 捕获阶段和冒泡阶段
在捕获阶段:
- 浏览器检查元素的最外层祖先<html>,是否在捕获阶段中注册了一个onclick事件处理程序,如果是,则运行它。
- 然后,它移动到<html>中单击元素的下一个祖先元素,并执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。
在冒泡阶段,恰恰相反:
- 浏览器检查实际点击的元素是否在冒泡阶段中注册了一个onclick事件处理程序,如果是,则运行它.
- 然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达<html>元素。
在现代浏览器中,默认情况下,所有事件处理程序都在冒泡阶段进行注册。
事件委托
冒泡允许我们利用事件委托——这个概念依赖于这样一个事实,如果你想要在大量子元素中单击任何一个都可以运行一段代码,可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。
为什么要用事件委托?
用事件委托就可以只用一次dom操作就能完成所有的效果,减少了dom操作,并且如果有新增的dom元素也可以很方便的处理事件绑定。
事件委托怎么做?
一个很好的例子是一系列列表项,如果想让每个列表项被点击时弹出一条信息,可以将click单击事件监听器设置在父元素<ul>上,这样事件就会从列表项冒泡到其父元素<ul>上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<ul>
<li>.</li>
<li>.</li>
<li>.</li>
</ul>
</div>
</body>
</html>
<script>
window.onload = function() {
const oUl = document.querySelector('ul');
// 想要点击li标签的时候绑定事件,直接绑定在父级元素上
oUl.onclick = function(evt) {
const event = evt || window.event;
// 利用event对象中的target属性,获取点击到的目标元素,进行判定
if (event.target.nodeName.toLowerCase() == 'li') {
event.target.innerHTML = '..'
}
}
}
</script>