实践后加深的理解
一:事件流
对下事件流程图的理解
二:事件委托
事件委托原理
- 大量同类型事件时,可以利用事件流的传递过程,将事件响应逻辑绑定在所有事件目标共同的祖先节点上,同时使用事件对象.target可以获取具体的事件目标节点进而获取事件目标的内容。
事件委托优点
- 由于事件处理逻辑绑定在祖先节点而不是各个事件目标上,那么只需在祖先节点注册一次事件即可,而不用管子节点有多少个,或者子节点的动态添加。
实践过程
一:事件捕获和事件冒泡
测试代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件流</title>
<style type="text/css">
#outer{
width: 150px;height: 150px;background-color: red;}
#inner{
width: 80px;height: 80px;background-color: green;}
</style>
</head>
<body>
<div id="outer">outer box
<div id="inner">inner box</div>
</div>
<script type="text/javascript">
let inner = document.getElementById('inner');
let outer = document.getElementById("outer");
let body = document.getElementsByTagName("body")[0];
let nodeArr = [inner,outer,body,document,window];
let tipsArr = ["inner","outer","body","document","window"];
nodeArr.forEach((ele,index)=>{
ele.addEventListener('click',(e)=>{
console.log(`${
tipsArr[index]} click 捕获`);
},true);
ele.addEventListener('click',(e)=>{
console.log(`${
tipsArr[index]} click 冒泡`);
},false);
});
</script>
</body>
</html>
运行结果(点击inner区域)
小细节:目标对象事件的捕获与冒泡与捕获事件/冒泡事件的执行顺序有关【测试如下】
nodeArr.forEach((ele, index)=> {
ele.addEventListener('click', (e)=> {
console.log(`${
tipsArr[index]} click 冒泡`);
}, false);
ele.addEventListener('click', (e)=> {
console.log(`${
tipsArr[index]} click 捕获`);
}, true);
});
- 运行结果(点击inner区域,也即目标对象事件为inner的捕获与冒泡)
捕获/冒泡拦截
nodeArr.forEach((ele, index)=> {
ele.addEventListener('click', (e)=> {
console.log(`${
tipsArr[index]} click 捕获`);
}, true);
ele.addEventListener('click', (e)=> {
console.log(`${
tipsArr[index]} click 冒泡`);
e.stopPropagation();
}, false);
});
- 运行结果
二:事件委托(代理)
测试代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
<style>
ul{
float: left;
}
</style>
</head>
<body>
<ul>
<li><button>one</button></li>
<li><button>two</button></li>
<li><button>three</button></li>
<li><button>four</button></li>
<li><button>five</button></li>
</ul>
<script>
let ul = document.getElementsByTagName('ul')[0];
ul.addEventListener('click', (e)=> {
let btn = e.target;
console.log(btn.textContent);
}, true);
function addLi(text){
let li = document.createElement('li');
let btn = document.createElement('button');
btn.textContent = text;
li.appendChild(btn);
ul.appendChild(li);
}
</script>
</body>
</html>
运行结果