JS自定义事件模拟事件总线

事件

Js与HTML之间的交互通过事件完成,事件,就是文档或浏览器窗口中发生的一些 特定的交互瞬间。事件类型有很多分类,例如:DOM事件类型,焦点事件,滚轮事件等等,说到这里就不得不说一下js的事件流

事件对象

无论是DOM0 还是 DOM2 在执行事件的时候,都会返回一个Event对象给我们。其中包含很多的属性,重点说下下面几个。
1.preventDefault,取消默认行为,例如a标签的跳转;相关的属性为cacelable,可以通过preventDefault取消默认行为,cacelable为true,否则为false
2.type 为出发该行为的事件是什么类型,例如click等
3.eventPhase 当前触发事件的阶段,是冒泡,捕获,还是目标阶段
4.stopPropagation 可以停止冒泡和捕获的继续传递
5.srcElement 和 target一样,事件的目标对象

自定义事件

除了平时使用的原生事件,有时候需要自定义事件。创建自定义事件的方法有两种,Event() 构造函数 和CustomEvent()构造函数,还有个createEvent()已经废弃,但是仍然有浏览器支持,所以我们暂且不说,有兴趣的可以自己看看。

Event()
支持两个参数:
1.typeArg 事件名称
2.eventInitOption 事件初始化配置,配置内容包含三个字段

参数 类型 说明
bubbles 布尔 表示该事件是否冒泡
cancelable 布尔 表示该事件能否被取消
composed 布尔 指示事件是否会在影子DOM根节点之外触发侦听器
1
2
3
4
5
6
7
8
// 创建事件
const ev = new Event('testEvent')
// 监听事件
document.addEventListener('testEvent', function () {
console.log('testEvent执行了')
})
// 触发事件
document.dispatchEvent(ev)

CustomEvent()

支持两个参数:
1.typeArg 事件名称
2.eventInitOption 事件初始化配置,配置内容包含事件部分字段,详情可以查看CustomEvent,额外还有一个detail字段可用于传递额外的参数

1
2
3
4
5
6
7
8
9
10
11
12
// 创建事件
const ev = new CustomEvent('testEvent', {
detail: {
extraParams: 1
}
})
// 监听事件
document.addEventListener('testEvent', function (e) {
console.log('testEvent执行了', e.detail)
})
// 触发事件
document.dispatchEvent(ev)
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
27
28
29
30
31
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title></title>
</head>

<body>
<div id="main"></div>
<script type="text/javascript">
function dispatchEvent(element, type, data) {
var event; // Event and CustomEvent on IE9-11 are global objects, not constructors

if(isFunction(Event) && isFunction(CustomEvent)) {
event = new CustomEvent(type, {
detail: data,
bubbles: true,
cancelable: true
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, data);
}

return element.dispatchEvent(event);
}
</script>
</body>

</html>

模拟事件总线

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 创建事件
const ev = new Event('testEvent')

const ev2 = new Event('testEvent2')
// 监听事件
document.addEventListener('testEvent', function () {
console.log('testEvent执行了-1')
})

document.addEventListener('testEvent', function () {
console.log('testEvent执行了-2')
})

document.addEventListener('testEvent2', function () {
console.log('testEvent执行了-3')
})

document.addEventListener('testEvent2', function () {
console.log('testEvent执行了-4')
})

document.addEventListener('testEvent2', function () {
console.log('testEvent执行了-5')
})
// 触发事件
document.dispatchEvent(ev)

setTimeout(() => {
document.dispatchEvent(ev2)
}, 1000)
</script>
</head>

<body>

</body>

</html>