一、 事件委托
- 事件委托:也可以称之为事件代理,给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪个子元素的事件。将事件委托给另外的元素,利用事件冒泡的特性,将里层的事件委托给外层事件,将事件绑定到目标元素的父节点,根据event对象的属性进行事件委托,改善性能。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。
-
事件委托的应用
1)新增的子元素是没有事件的,说明添加子节点的时候,事件没有一起添加进去
2)子元素太多,一个个循环遍历添加事件耗费性能
-
事件委托的原理
1)利用事件冒泡的特性,将里层的事件委托给外层事件,根据event对象的属性进行事件委托,改善性能
2)使用事件委托能够避免对特定的每个节点添加事件监听器;事件监听器是被添加到它们的父元素上
3)事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件
- 事件委托的好处:使用事件委托,可以大大减少与DOM交互操作的次数,可以提供性能优化。在性能优化中,主要思想操作之一就是减少DOM的操作,内存的占用率就会减小。
二、事件委托的实例
-
事件委托的理解:
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
</head>
<body>
<ul id="list">
<li>我是第一个li</li>
<li>我是第二个li</li>
<li>我是第三个li</li>
<li>我是第四个li</li>
<li>我是第五个li</li>
</ul>
</body>
<script>
window.onload = function(){
var list = document.getElementById("list");
var li = document.getElementsByTagName("li");
list.onmouseover = function(env){
// 兼容获取event对象
var env = env || window.event;
// 兼容获取目标对象 env.target为标准 env.srcElement为IE
var target = env.target || env.srcElement;
// 判断目标对象是否是li
// target.nodeName 可以获取节点名称,通过toLowerCase()可以将节点名称的大小转换为小写
if(target.nodeName.toLowerCase()=== "li"){
target.style.background = "red";
}
}
}
</script>
</html>
说明:需求分析是定义一个无序列表,当鼠标移入的时候,能够让指定的li去变颜色。如果通过循环遍历给每一个li添加移入事件,会浪费性能,内存占用率就会过高。这个时候可以通过冒泡原理采取委托事件提高性能优化。获取ul和li,给ul绑定鼠标移入事件,相当于给父级添加移入事件,这样不管移入哪一个li都会触发父级的移入事件。在移入事件中,兼容获取event对象和目标对象,判断事件源,找到目标对象的li,并且执行相应的变色操作。
-
利用事件委托分别实现不同的效果
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
</head>
<body>
<ul id="list">
<li id="li1">我是第一个li</li>
<li id="li2">我是第二个li</li>
<li id="li3">我是第三个li</li>
<li id="li4">我是第四个li</li>
<li id="li5">我是第五个li</li>
</ul>
</body>
<script>
window.onload = function(){
var list = document.getElementById("list");
var li = document.getElementsByTagName("li");
list.onmouseover = function(env){
var env = env || window.event;
var target = env.target || env.srcElement;
if(target.nodeName.toLowerCase()==="li"){
// 通过switch语句分别给li执行不同的操作
switch (target.id){
case "li1":
target.style.background = "red";
break;
case "li2":
target.style.background = "pink";
break;
case "li3":
target.style.background = "orange";
break;
case "li4":
target.style.background = "purple";
break;
case "li5":
target.style.background = "blue";
break;
}
}
}
};
</script>
</html>
说明:需求分析是当点击不同的li的时候,li会实现不同的颜色效果。采取事件委托的方式,先获取ul和li元素,给父级元素ul绑定鼠标移入事件,兼容获取event对象和目标对象,找到事件源,通过switch语句,进行具体的li,分别给li添加不同的效果,这样就减少了dom操作,提高了性能优化。
-
通过监听器进行事件委托
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
</head>
<body>
<ul id="list">
<li>我是第一个li</li>
<li>我是第二个li</li>
<li>我是第三个li</li>
<li>我是第四个li</li>
<li>我是第五个li</li>
</ul>
</body>
<script>
var list = document.getElementById("list");
list.addEventListener("click",function(env){
console.log(env.target.innerHTML);
});
</script>
</html>
说明:需求分析是定义一个无序列表,当点击li的时候,对应的li的内容会输出在控制台中。第一步是给父元素ul绑定事件,通过addEventListener监听绑定click点击事件。第二步是监听子元素的冒泡事件,当点击子元素li的时候会向上进行冒泡。 第三步是通过匿名函数获取触发事件的目标,找到是哪一个子元素的事件。这样当鼠标点击的li的时候,对应的li的内容也会输出在控制台中。