在冒泡事件中绑定冒泡事件
先看代码
<div id="container">
<div id="div"></div>
</div>
<script>
const div = document.getElementById('div');
const con = document.getElementById('container');
div.addEventListener('click', function (e) {
console.log('child click' + 111111);
con.addEventListener('click', function () {
console.log('father click' + 222222);
})
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
父元素没有绑定事件,子元素绑定了点击事件,并同时给父元素绑定了一个点击事件,可以看一看,点击子元素之后输出的结果是怎么样的。
- 结果:新绑定的father click也被触发了。
这里可以得出,事件冒泡的传递事件,是在绑定的handler触发之后的,但是最大多数情况下,我们肯定是不想让父元素新绑定的 click 触发的,不然图啥呢,直接初始化绑定就好了,也不用写在子元素的 handler 中。 那怎么解决呢,加个setTimeout(0)去给父元素添加事件,确实可以解决了这个问题。但是会让代码的可读性降了一个档次。
# 解决办法
事件触发时,有一个 timeStamp, createInvoker记录了元素绑定的时间,在接受到事件的时候,通过 timeStamp 和 attached 的比较,来决定是否运行这个事件绑定的 handler
Object.prototype.createEventListener = function (...args) {
// handler
const func = args[1];
const invoker = function (...arguments) {
const event = arguments[0];
// 比较event触发的时间,和事件绑定的时间,如果event触发时候,事件还未绑定,则不运行
if (event.timeStamp >= invoker.attached) {
func(...arguments)
}
}
// handler被绑定上的时间
invoker.attached = performance.now();
// 替换原来的handler
args[1] = invoker;
return this.addEventListener(...args);
}
div.createEventListener('click', function (e) {
console.log('child click' + 111111);
con.createEventListener('click', function () {
console.log('father click' + 222222);
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
点击第一次只有 child 打印,第二次点击,child 和 father 一起打印。
最近更新时间: 2021/08/25 17:25:09
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00