在介绍JS中事件委派之前先来看看一个简单的需求:为每一个超链接绑定一个单击响应函数并在控制台打印一句话,内容是:” a 标签的单击响应函数“。下面是这个需求的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
// 需求:为每一个超链接绑定一个单机响应函数
window.onload = function() {
// 获取页面中所有的 a 标签
var allA = document.getElementsByTagName('a');
for(var i = 0; i < allA.length; i++) {
allA[i].onclick = function() {
console.log('我是 a 的单击响应函数');
}
}
}
</script>
</head>
<body>
<ul id="ul">
<li><a href="javascript:;">超链接1</a></li>
<li><a href="javascript:;">超链接2</a></li>
<li><a href="javascript:;">超链接3</a></li>
</ul>
</body>
</html>
在浏览器中打开上部分代码,点击相应的超链接, 都可以在控制台打印“我是 a 的单击响应函数”。感觉好像是够用了,哈哈哈哈,其实还没完。
在此基础上升级,现在要做的是点击添加按钮追加一个 ul 的子元素 li。被新添加进去的 li 也能触发循环绑定的事件方法,下面是具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function () {
var ul = document.getElementById('ul');
var allA = document.getElementsByTagName('a');
var btn = document.getElementById('btn');
btn.onclick = function () {
// 创建一个li标签
var li = document.createElement('li');
li.innerHTML = '<a href="javascript:;" class="link">新添加的超链接</a>';
ul.appendChild(li);
}
for (var i = 0; i < allA.length; i++) {
allA[i].onclick = function () {
console.log('我是 a 的单击响应函数');
}
}
}
</script>
</head>
<body>
<button id="btn">点击添加</button>
<ul id="ul">
<li><a href="javascript:;">超链接1</a></li>
<li><a href="javascript:;">超链接2</a></li>
<li><a href="javascript:;">超链接3</a></li>
</ul>
</body>
</html>
在浏览器打开,点击添加一个子元素,可以看到之前循环绑定事件的函数不管用了,被新添加的元素不会触发 onclick 事件方法,不能在控制台打印 “我是a标签的响应函数 ”,这里就涉及到事件委派了,先来看看事件委派的原理。
事件委派:将事件统一绑定给元素共同的祖先元素(后代元素事件触发时,通过冒泡,通过祖先元素的响应函数来处理事件),这样可以只绑定一次,即可应用到多个元素上。事件的委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能event中的target表示的触发事件的对象 ,使用它对触发事件的元素进行判断。
我现在的需求是:只需要绑定一次事件并可以应用到多个元素上,即使元素是后添加的,也能触发这个事件方法。具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 需求:为每一个li绑定一个函数 -->
<button id="btn">点击添加超链接</button>
<ul id="ul" style="background-color: pink">
<li><a href="javascript:;" class="link">超链接1</a></li>
<li><a href="javascript:;" class="link">超链接2</a></li>
<li><a href="javascript:;" class="link">超链接3</a></li>
</ul>
<script>
window.onload = function () {
var ul = document.getElementById('ul');
var btn = document.getElementById('btn');
btn.onclick = function () {
// 创建一个li标签
var li = document.createElement('li');
li.innerHTML = '<a href="javascript:;" class="link">新添加的超链接</a>';
ul.appendChild(li);
}
var allA = document.getElementsByTagName('a');
ul.onclick = function (event) {
if (event.target.className == 'link') {
alert(`我是a`);
}
}
}
</script>
</body>
</html>
target 返回目标元素,表示触发事件的对象。