一、冒泡和捕捉
1、冒泡
当一个事件发生在一个元素上,它会首先运行在该元素上的处理程序,然后运行其父元素上的处理程序,然后一直向上到其他祖先上的处理程序
javascript
<div class="box" onclick="console.log('1')">box
<div class="box" onclick="console.log('2')">form
<div class="box" onclick="console.log('3')">ted
<p onclick="console.log('4')">pppp</p>
</div>
</div>
</div>
点击p后,会输出4,然后依次继续输出3,2,1
2、event.target
引发事件的那个嵌套层级最深的元素被称为目标元素,可以通过 event.target
访问
event.target ------ 是引发事件的"目标"元素,它在冒泡过程中不会发生变化。
this ------ 是"当前"元素,其中有一个当前正在运行的处理程序。
3、停止冒泡
e.stopPropagation() 阻止向上冒泡,但是当前元素上的其他处理程序都会继续运行
javascript
box1.onclick = function (e) {
console.log('1')
}
box2.onclick = function (e) {
e.stopPropagation() // 阻止冒泡 不会继续父辈的"输出1"点击事件:
console.log('2')
}
box3.onclick = function (e) {
console.log('3')
}
p.onclick = function (e) {
console.log('p')
// e.stopPropagation()
}
4、捕获
为了在捕获阶段捕获事件,需要将处理程序的 capture
选项设置为 true
box2.addEventListener("click", () => {
console.log("2")
}, { capture: true })
在某个位置触发事件后,会先从父元素向内执行捕获阶段,抵达位置之后向父元素执行冒泡阶段
二、事件委托
如果有许多以类似方式处理的元素,那么就不必为每个元素分配一个处理程序 ------ 而是将单个处理程序放在它们的共同祖先上
javascript
<body>
<div id="menus">
<button id="btn1">删除</button>
<button id="btn2">添加</button>
<button id="btn3">编辑</button>
</div>
<script>
// 事件委托
// 如果我们有许多以类似方式处理的元素,那么就不必为每个元素分配一个处理程序 ------ 而是将单个处理程序放在它们的共同祖先上
const menus = document.getElementById("menus")
menus.onclick = (e) => {
console.log(e.target.id);
switch (e.target.id) {
case "btn1":
console.log("delete");
break;
case "btn2":
console.log("add")
break;
case "btn3":
console.log("edit");
break;
}
}
</script>
</body>
1、标记中的行为
javascript
<body>
<!-- 标记中的行为 -->
<!-- 为整个菜单添加一个处理程序,并为具有方法调用的按钮添加 data-action 特性 -->
<button data-action="btn1">删除</button>
<button data-action="btn2">添加</button>
<button data-action="btn3">编辑</button>
<script>
document.onclick = (e) => {
switch (e.target.dataset.action) {
case "btn1":
console.log("delete");
break;
case "btn2":
console.log("add")
break;
case "btn3":
console.log("edit");
break;
}
}
</script>
</body>
2、行为模式
- 我们将自定义特性添加到描述其行为的元素。
- 用文档范围级的处理程序追踪事件,如果事件发生在具有特定特性的元素上 ------ 则执行行为(action)。
javascript
<body>
计数器1:<input type="button" value="1" data-counter>
<hr>
计数器2:<input type="button" value="2" data-counter>
<script>
document.onclick = (e) => {
if (e.target.dataset.counter !== undefined) {
e.target.value++;
}
}
</script>
</body>