<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件模型:捕获与冒泡</title>
<style>
div{
border: 1px solid red;
padding: 20px;
}
</style>
</head>
<body>
<div id="grandfather">
爷爷
<div id="father">
爸爸
<div id="son">
儿子
</div>
</div>
</div>
<script>
son.addEventListener('click',function () {
console.log('son')
})
father.addEventListener('click',function () {
console.log('father')
})
grandfather.addEventListener('click',function () {
console.log('grandfather')
})
</script>
</body>
</html>
image.png
当点击"儿子"区域时,会在控制台打出什么样的结果呢?首先,值得肯定的是,点击后,无论是"爸爸",还是"爷爷"都会触发"onclick"事件,只是执行的顺序应该是怎么样的呢?最先IE认为,执行的顺序应该是"爷爷"->''爸爸''->''儿子",这种执行顺序被称作
event capturing
。而Microsoft则不这样认为,他们认为先被点击的块具有执行优先权,所以触发事件的顺序应该是:"儿子"->''爸爸''->''爷爷'',这种执行的顺序则被称为: event bubbling
。所以W3C为此做了标准,于是乎,W3C标准采取了所谓的"两全其美"的方案。事件模型中发生的任何事件,先从祖先元素一路向下开始捕获,直到达到目标元素,达到目标元素后开始冒泡,W3C事件模型如下: image.png
如果想让执行的顺序是
event bubbling
只需要:在DOM level2的event写法后添加一个 true即可: son.addEventListener('click',function () {
console.log('son')
},true)
father.addEventListener('click',function () {
console.log('father')
},true)
grandfather.addEventListener('click',function () {
console.log('grandfather')
},true)
当在事件最后加上个true后,在控制台打印的顺序为:"爷爷"->''爸爸''->''儿子"。当事件最后不写,或值为falsy时(0,'',null,undefined,NaN)时,则执行的顺序为事件冒泡顺序:
son.addEventListener('click',function () {
console.log('son')
},false)
father.addEventListener('click',function () {
console.log('father')
},false)
grandfather.addEventListener('click',function () {
console.log('grandfather')
},false)
在控制台打印的顺序为:"儿子"->''爸爸''->''爷爷"。