在介绍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 返回目标元素,表示触发事件的对象。