什么是事件委托:
事件委托——给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪个子元素的事件。(不理解冒泡的可以去百度下)
定义:
利用事件冒泡处理动态元素事件绑定的方法,专业术语叫事件委托。 使用事件委托技术可以避免对特定的每个节点添加事件监听器,相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。
事件委托的好处:
事件委托技术可以避免对每个字元素添加事件监听器,减少操作DOM节点的次数,从而减少浏览器的重绘和重排,提高代码的性能。
使用事件委托,只有父元素与DOM存在交互,其他的操作都是在JS虚拟内存中完成的,这样就大大提高了性能。
什么时候用事件委托:
当子元素有很多,需要对子元素的时间进行监听的时候
案例:
(1)原生JS实现事件委托效果
<!DOCTYPE html> <html> <head> <title>事件委托测试</title> </head> <body> <style type="text/css"> *{margin: 0;padding: 0;} a{text-decoration: none;} ul,li{list-style: none;} div{display: block; 500px;padding: 200px 0 0 200px;} div ul li{display: block; 100%;text-align: center;height: 35px;line-height: 35px;} div ul li:nth-child(2n){background: #f00;} </style> <div> <ul> <li><a>测试1</a></li> <li><a>测试2</a></li> <li><a>测试3</a></li> <li><a>测试4</a></li> <li><a>测试5</a></li> <li><a>测试6</a></li> <li><a>测试7</a></li> <li><a>测试8</a></li> </ul> </div> <script type="text/javascript"> document.getElementsByTagName("ul")[0].addEventListener('click',function(e){ alert("点击的内容是:"+e.target.innerHTML); }); </script> </body> </html>
事件委托三部曲:
第一步:给父元素绑定事件
给元素ul添加绑定事件,通过addEventListener为点击事件click添加绑定
第二步:监听子元素的冒泡事件
这里默认是冒泡,点击子元素li会向上冒泡
第三步:找到是哪个子元素的事件
通过匿名回调函数的参数e用来接收事件对象,通过target获取触发事件的目标
JQ实现事件委托:
<!DOCTYPE html> <html> <head> <title>事件委托测试</title> </head> <body> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> <style type="text/css"> *{margin: 0;padding: 0;} a{text-decoration: none;} ul,li{list-style: none;} div{display: block; 500px;padding: 200px 0 0 200px;} div ul li{display: block; 100%;text-align: center;height: 35px;line-height: 35px;} div ul li:nth-child(2n){background: #f00;} </style> <div> <ul> <li><a>测试1</a></li> <li><a>测试2</a></li> <li><a>测试3</a></li> <li><a>测试4</a></li> <li><a>测试5</a></li> <li><a>测试6</a></li> <li><a>测试7</a></li> <li><a>测试8</a></li> </ul> </div> <script type="text/javascript"> $("ul").on('click',function(e){ alert("点击的内容是:"+$(e.target).text()); }); </script> </body> </html>
事件委托在面试中还是经常被问到的,
比如下面的代码
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul>
现在问题来了?怎么样高效的给li元素绑定事件,当用户单击li元素的时候能够提示li元素中的内容?
如果这个用JQUERY来做很好解决
$(function(){
$("li").on("click",funcition(){
alert($(this).text()); 或者写成 alert($(this).html());
}
})
但是用原生的JS来写最初的想法是:
window.onload = function() {
var ul = document.getElementById("ul");
var lis = ul.getElementsByTagName("li"); //注意这个地方有错误,getElementsByTagName 是document的方法,写在ul 上有有错误的。所以必须写成
var lis = document.getElementsByTagName("li");
for(var i = lis.length-1;i>=0;i--) {
lis[i].onclick = function() {
alert(this.innerHTML);
}
}
}
这种想法是最简单也是最直观 也是正确的,但是存在一定的问题,当DOM中的li
元素特别多的时候,这样的循环遍历的绑定操作势必会占用大量的资源,这个时候
我们可以使用事件的一些特性,将操作绑定到ul元素上面,当事件触发时,自动获取
当前事件操作的对象,然后再完成操作,来看下面的代码:
window.onload = function(){
var ul = document.getElementById("ul");
ul.onclick=function(e) {
e = window.event?window.event:e; // 这个地方也可以写成 e = e || window.event;
//是为了更好的兼容IE浏览器和非ie浏览器。
//在ie浏览器中,window.event
是全局变量,在非ie中,就需要自己传入一个参数来获取event啦,所以就有了var e = e||window.event
var who = e.target?e.target : e.srcElement;
alert(who.innerHTML);
}
}