事件代理的实现原理,实例演示
实例效果:
实例源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>事件代理的实现原理,实例演示</title>
</head>
<body>
<div class="first">
<div class="second">
<div class="three">事件传递</div>
</div>
</div>
<script>
// 事件的捕获和冒泡
const first = document.querySelector(".first");
const second = document.querySelector(".second");
const three = document.querySelector(".three");
// true: 捕获阶段, false: 冒泡阶段
// addEventListener(evName, callback, true);
// ev.target: 事件的触发者, ev.currentTarget: 事件的绑定者
// true: 捕获阶段
first.addEventListener(
// %s:占位符
"click",
(ev) =>
console.log(
"捕获:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
true
);
second.addEventListener(
"click",
(ev) =>
console.log(
"捕获:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
true
);
three.addEventListener(
"click",
(ev) =>
console.log(
"捕获:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
true
);
// false: 冒泡阶段
first.addEventListener(
"click",
(ev) =>
console.log(
"冒泡:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
false
);
second.addEventListener(
"click",
(ev) =>
console.log(
"冒泡:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
false
);
three.addEventListener(
"click",
(ev) =>
console.log(
"冒泡:触发 %s, 绑定 %s",
ev.target.classList.item(0),
ev.currentTarget.classList.item(0)
),
false
);
</script>
<!-- 冒泡实现事件委托 / 事件代理 -->
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
<script>
// 给每一个 < li > 逐个添加点击事件;
// document
// .querySelectorAll("ul li")
// .forEach((item) =>
// item.addEventListener(
// "click",
// (ev) =>
// console.log("触发 %s, 绑定 %s", ev.target, ev.currentTarget),
// false
// )
// );
// 根据冒泡原理,子元素的同名事件会向上冒泡到父级元素的同名事件上,所以直接将这个事件干脆添加给它的父元素就可以
document
.querySelector("ul")
.addEventListener(
"click",
(ev) => console.log("触发 %s, 绑定 %s", ev.target, ev.currentTarget),
false
);
// 将应该在子元素的触发的事件,委托给父元素去触发了, 可以极大的简化代码和业务逻辑
</script>
</body>
</html>
实例总结:
事件的捕获和冒泡:
- true: 捕获阶段, false: 冒泡阶段
- addEventListener(evName, callback, true);
- ev.target: 事件的触发者, ev.currentTarget: 事件的绑定者
冒泡实现事件委托/事件代理:
- 冒泡原理,子元素的同名事件会向上冒泡到父级元素的同名事件上,所以直接将这个事件干脆添加给它的父元素就可以
- 将应该在子元素的触发的事件,委托给父元素去触发了, 可以极大的简化代码和业务逻辑