什么是JS的事件流?--事件机制
事件流描述的是从页面接收事件的顺序
一个事件的触发会涉及到哪些阶段
- 从window层往事件触发处传播,直到遇到注册的捕获事件会触发
//addEventListener用来给Dom节点注册一个点击事件
document.getElementById('root').addEventListener('click', function(){
console.log(123)
})
- 传播到事件触发处时,触发注册事件
- 从事件触发处往window传播,遇到注册的冒泡事件会触发
这里疑惑就来了,好像听说浏览器的事件流是事件冒泡啊?怎么会变成先捕获后冒泡了呢?
addEventListener的第三个参数
addEventListener接收三个参数:
- 要处理的事件名
- 作为事件处理程序的函数
- 一个布尔值
最后这个布尔值表示事件处理程序执行的阶段,默认为false,表示在冒泡阶段处理程序,若设为true则表示在捕获阶段执行。
<div id="parent" style="width:80px; height:80px; background:yellow">
<div id="child" style="width:40px; height:40px; background:red"></div>
</div>
<script>
var parent = document.getElementById('parent')
var child = document.getElementById('child')
parent.addEventListener('click', function(event){
console.log('父盒子')
}, true)
child.addEventListener('click', function(event) {
console.log('子盒子')
}, false)
</script>
以上代码若不设置第三个值,则默认冒泡阶段执行事件处理程序,打印顺序为子盒子->父盒子
若设为以上形式,则表示父盒子事件再捕获阶段就去执行,而子盒子仍再冒泡阶段执行,因此打印顺序为父盒子->子盒子
具体阶段如图所示:

阻止冒泡
child.addEventListener('click', function(event) {
// 会阻止冒泡以及该容器之后所有的点击事件
event.stopImmediatePropagation()
// 只阻止冒泡
event.stopPropagation()
console.log('子盒子')
}, false)
事件处理程序(事件侦听器)
事件处理程序表示响应某个事件的函数(以on开头)
目前主要支持的有三种:
- DOM0级事件处理程序
- DOM2级事件处理程序
- IE级事件处理程序
DOM0级事件处理程序
DOM0级的事件处理程序是在绑定事件的元素的作用域中运行
var btn = document.getElementById('myBtn')
btn.onclick = function () {
console.log(this.id) // myBtn
}
// 删除DOM0级方法指定的事件处理程序
btn.onclick = null
这种形式书写较为直观,简洁,但缺点 只支持一个事件处理程序
DMO2级事件处理程序
定义了两个方法
-
addEventListener()
-
removeEventListener()
所有的DOM节点都包含这两个方法,接收三个参数:要处理的时间名、作为事件处理程序的函数、事件流形式
作用域:其依附元素的作用域种运行
优点:可以添加多个事件处理程序,并顺序执行
IE事件处理程序
定义了两个方法
- attachEvent()
- detachEvent()
接收两个相同的参数:事件处理名称和事件处理程序函数
作用域:事件处理程序会在全局作用域中运行
var btn = document.getElementById('myBtn')
btn.attachEvent("onclick", function(){
console.log(this === window) // true
})
区别:可以为一个元素添加多个事件处理程序,倒序执行
三种事件处理程序对比
| 对比 | DOM0级 | DOM2级 | IE级 |
|---|---|---|---|
| 形式 | element.onclick | element.addEventListener('onclck',callback,false) | element.attachEvent('onclick',callback) |
| 执行阶段 | 冒泡阶段 | 冒泡(默认)/捕获阶段 | 冒泡阶段 |
| 作用域 | 其依附元素的作用域 | 其依附元素的作用域 | 事件处理程序会在全局作用域中运行 |
| 多个事件处理程序 | 不支持(唯一) | 支持,且顺序执行 | 支持,倒序执行 |