一 什么是DOM事件模型
- 请看如下代码,当点击son时,算不算点击了parent?答案是算
- 那么如果此时parent和son分别绑定点击事件fn1和fn2,那么先执行fn1还是fn2呢?答案是不一定。因为浏览器同时支持两种顺序,先执行fn1再执行fn2的顺序,和先执行fn2再执行fn1的顺序。具体哪种执行方式在绑定监听事件的时候指定。
<div class="parent">
<div class="son">
</div>
</div>
二 DOM2级事件模型
- 事件捕获和事件冒泡的机制如下图

- 首先事件捕获阶段,按"window->document->html->body->......->目标元素"的顺序有没有函数监听,接着事件冒泡阶段,反向传递。整个过程中,有监听函数就调用,并提供事件信息,没有就跳过。
- 无论绑定事件时,选择捕获阶段执行还是冒泡阶段执行,仅仅只是选择绑定事件函数在那个阶段执行,这两个阶段最终都会经历,而且是先捕获阶段,再冒泡阶段。
三 事件绑定API
- 在DOM2级事件模型中使用addEventListener和removeEventListener来注册和解除事件(IE8及之前版本不支持)。这种函数较之之前的方法好处是一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。
- 由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡。
addEventListener('事件名称','事件回调',bool('捕获/冒泡'))
四 Event 对象有哪些常用应用?
- 阻止默认事件:event.preventDefault(),有些事件不能阻止默认动作,(scroll事件)
- 阻止冒泡:event.stopPropagation(),所有冒泡都可取消
- 阻止调用相同事件的其他侦听器(事件响应优先级):event.stopImmediatePropagation()
- 当前绑定事件的元素:event.currentTarget
- 当前被点击的元素:event.target
五 举例
- 输出2,1
<div class="test1">
<div class="test2"></div>
</div>
<script>
document.querySelector('.test1').addEventListener('click',function () {
console.log(1)
})
document.querySelector('.test2').addEventListener('click',function () {
console.log(2)
})
</script>
- 输出1,2
<div class="test1">
<div class="test2"></div>
</div>
<script>
document.querySelector('.test1').addEventListener('click', function () {
console.log(1)
}, true)
document.querySelector('.test2').addEventListener('click', function () {
console.log(2)
}, true)
</script>
- 输出2,1
<div class="test1">
<div class="test2"></div>
</div>
<script>
document.querySelector('.test1').addEventListener('click', function () {
console.log(1)
})
document.querySelector('.test2').addEventListener('click', function () {
console.log(2)
}, true)
</script>
- 输出1,2
<div class="test1"></div>
<script>
document.querySelector('.test1').addEventListener('click', function () {
console.log(1)
})
document.querySelector('.test1').addEventListener('click', function () {
console.log(2)
}, true)
</script>
六 如何阻止滚动
- 要阻止scroll,可阻止wheel和touchstart的默认动作,再让CSS让滚动条的width:0;
- CSS也行,使用overflow:hidden可以直接取消滚动条,但此时JS仍然可以修改scrollTop