shizhihuaxu / study-notes

学习笔记,见 issues
0 stars 0 forks source link

事件处理模型 #12

Open shizhihuaxu opened 4 years ago

shizhihuaxu commented 4 years ago
<div class='parent'>
    <div class='child'>
    </div>
</div>

// 形式一:均在捕获
parent.addEventListener('click', e => {
   console.log(1);
})
child.addEventListener('click', e => {
   console.log(2);
})

// 形式二:parent 在捕获,child 在冒泡
parent.addEventListener('click', e => {
   console.log(1);
}, true)
child.addEventListener('click', e => {
   console.log(2);
}, false)

// 形式三:均在冒泡
parent.onclick = function() {
    console.log(1)
}
child.onclick = function() {
    console.log(2)
}

// 形式四:parent、child 均在冒泡,child 阻止了事件冒泡
parent.addEventListener('click', e => {
   console.log(1);
})
child.addEventListener('click', e => {
   console.log(2);
    e.stopPropagation()
})

// 形式五:parent 在捕获,child 在冒泡,child 阻止了事件冒泡
parent.addEventListener('click', e => {
   console.log(1);
}, true)
child.addEventListener('click', e => {
   console.log(2);
    e.stopPropagation()
})

上面的事件,当点击 child 是,输出顺序是怎样的呢?

形式一:冒泡阶段执行,输出 2,1

形式二:parent 在捕获阶段,child 在冒泡阶段,输出 1,2

形式三:均在冒泡阶段执行,输出 2,1

形式四:均在冒泡阶段执行,但子元素阻止了事件冒泡,所以只输出 2

形式五:parent 在捕获,child 在冒泡,child 阻止了事件冒泡,依然输出 1,2

两种事件模型:捕获和冒泡

捕获(capture):从祖先元素开始向触发的目标元素开始触发事件,执行绑定在捕获阶段的事件

冒泡(bubbling):先从触发的目标元素开始触发事件,向祖先元素冒泡执行,执行绑定在冒泡阶段的事件

绑定事件的方式

w3c: addEventListener 第三个参数为 useCapture 是否使用捕获,默认 false,使用冒泡

IE 8.0 以下: 使用 attachEvent 仅支持冒泡

onclick: 仅支持冒泡

​ w3c 都是先捕获直到到达触发事件的目标元素,然后再从此元素向祖先冒泡;看父子元素初始化事件时,指定的是在捕获阶段执行还是在冒泡阶段执行,从而可以得出执行的先后顺序。

阻止事件冒泡和捕获

w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

阻止默认事件
e.preventDefault
获取事件触发的目标元素
e.target/srcElement

获取当前执行事件的元素

e.currentTarget