大家到现在所了解到的事件,基本都离不开浏览器的行为。
比如点击鼠标、按下键盘等等,这些都可以被浏览器感知到,进而帮助我们转换成一个“信号”触发对应处理函数。
但是还有一些行为,是浏览器感知不到的。比如说看这样一段 html

1
2
3
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>

如果我们仅仅想监听 a 这个元素上的点击行为,我们可以用 addEventListener 来安装监听函数

1
2
3
4
var a = document.getElementById("a");
document.addEventListener("click", function () {
console.log("a");
});

但是,如果现在想实现这样一种效果
在点击A之后,B 和 C 都能感知到 A 被点击了,并且做出相应的行为——就像这个点击事件是点在 B 和 C 上一样。
我们知道,借助时间捕获和冒泡的特性,我们是可以实现父子元素之间的行为联动的。
但是此处,A、B、C三者位于同一层级,他们怎么相互感知对方身上发生了什么事情呢?

“A被点击了”这件事情,可以作为一个事件来派发出去,由 B 和 C 来监听这个事件,并执行各自身上安装的对应的处理函数。在这个思路里,“A被点击了”这个动作挺特别,特别就特别在浏览器不认识它。因为浏览器不认识它,所以浏览器不肯”帮忙“,不会帮咱去感知和派发这个动作。不过没关系,感知和派发,咱都可以自己来实现
首先大家需要了解的是,自定义事件的创建。比如说咱们要创建一个本来不存在的”clickA”事件,来表示 A 被点击了,可以这么写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<script>
/* 获取元素 */
const a = document.querySelector(".a")
const b = document.querySelector(".b")
const c = document.querySelector(".c")
/* 创建一个自定义事件 */
const aEvent = new Event("sb250")
a.addEventListener("click", function (e) {
console.log('a');
/* 派发给b和c */
b.dispatchEvent(aEvent)
c.dispatchEvent(aEvent)
})
/* b监听 */
b.addEventListener("sb250", function (e) {
console.log('b')
})
c.addEventListener("sb250", function (e) {
console.log('c')
})
</script>

可以看到,浏览器控制台能正确的打印 a b c,因此实现了对a点击事件的监听