DOM事件
Contents
事件流
事件两种模型:捕获和冒泡
javascript复制代码// 鼠标点击子元素后,打印顺序为
// 父捕获
// 子捕获
// 子冒泡
// 父冒泡
<html>
<div class="parent">
<div class="child">子元素</div>
</div>
<script>
let parentDom = document.querySelector('.parent');
parentDom.addEventListener('click', function () {console.log('父捕获'); }, true)
parentDom.addEventListener('click', function () {console.log('父冒泡');}, false)
let childDom = document.querySelector('.child')
childDom.addEventListener('click', function () {console.log('子捕获');}, true)
childDom.addEventListener('click', function () {console.log('子冒泡');}, false)
</script>
</html>
流程:
- 捕获
- 目标阶段
- 冒泡
事件捕获流程
从上到下
window -> document -> html -> body->元素
Event 对象
event.preventDefault()
event.stopPropagation()
event.stopImmediatePropagation()
event.target
event.currentTarget
函数 | 作用 |
---|---|
event.stopImmediatePropagation() | 能阻止父类元素冒泡,也会阻止当前节点的其他事件处理。 |
event.stopPropagation() | 阻止父类元素的冒泡,不影响当前节点的其他事件处理。 |
event.targe | 事件的真正发出者 |
event.currentTarget | 监听事件者 |
节点绑定多个事件,先绑定的事件会处理。
例子:
<div id="div">
<input type="text" id="input"/>
</div>
var dom = document.querySelector('#input');
dom.addEventListener('keyup', function (e) {
console.log('keyup 1');
})
dom.addEventListener('keyup', function (e) {
console.log('keyup 2');
})
dom.addEventListener('click', function (e) {
//e.stopPropagation();
e.stopImmediatePropagation();
console.log('dom click 1');
})
dom.addEventListener('click', function (e) {
console.log('dom click 2');
})
var div = document.querySelector('#div');
div.addEventListener('click', function (e) {
console.log('div click 1');
})
div.addEventListener('click', function (e) {
console.log('div click 2');
})
结果说明:
- 调用
stopPropagation
方法后,dom click 1
,dom click2
执行。阻止冒泡,父类元素的事同类事件不会执行。blur
,keyup
事件触发后会依次执行。 - 调用
stopImmediatePropagation
方法后,点击输入框,只会执行dom click1
。阻止冒泡,父类元素的事同类事件不会执行。blur
,keyup
事件触发后会依次执行。
事件委托(代理)
利用冒泡的原理,将元素的事件委托给它的父级或者更外级的元素处理。
优点
- 同类元素的事件委托给上级元素,不需要给每个元素都绑定事件,减少内存占用,提升性能
- 动态新增元素无需重新绑定事件。
缺点
- 利用事件冒泡的原理,不支持不冒泡的事件;
- 层级过多,冒泡过程中,可能会被某层阻止掉;
- 把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。
注意点
- 事件委托的实现依靠的冒泡,因此不支持事件冒泡的事件就不适合使用事件委托。