一、事件的三个阶段
在 DOM 事件流中,事件分为三种阶段:捕获、目标、冒泡。
- 捕获:事件触发的时候,事件顺序从外到内依次触发
- 目标:事件触发的 DOM 对象本身
- 冒泡:事件顺序从外到内依次触发
二、事件的执行顺序
- 非目标元素时:
按照 W3C 标准的事件是:捕获 =》目标 =》 冒泡
例如:
在捕获和冒泡都允许的情况下(addEventListener的第三个参数true为捕获,false为冒泡,默认是false)
事件顺序是:UL > LI > SPAN > BODY,即先捕获再冒泡
2. 在同一目标元素下
- 若捕获和触发都存在,先触发捕获,再触发冒泡
function consoleFunc(e) {
console.log(111)
}
function consoleFunc2(e) {
console.log(222)
}
li.addEventListener("click", consoleFunc, false)
li.addEventListener("click", consoleFunc2, true)
执行顺序:222 > 111
- 若均为捕获或者均为冒泡,则先按代码先后顺序触发
即,将上述代码改成
li.addEventListener("click", consoleFunc, true)
li.addEventListener("click", consoleFunc2, true)
执行顺序:111 > 222
3. onclick 函数执行顺序
onclick 函数执行默认按冒泡方式进行,即从内而外
三、stopPropagation() 和 stopImmediatePropagation() 区别
作用:均为阻止事件的冒泡或捕获
注意:很多人将stopPropagation()和preventDefault()混淆,后者为阻止默认事件,a链接,表单submit提交之类的事件
- stopPropagation()
- stopImmediatePropagation() --- 该方法还可以阻止其他事情发生
例1:下面这段代码,点击 p 标签执行结果就是:P
如果注释掉 stopImmediatePropagation(),则会打印:P 和 111
<body>
<div id="div">
<p id="p"></p>
</div>
<script>
var div = document.getElementById("div")
var p = document.getElementById("p")
function consoleFunc(e) {
//e.stopPropagation()
e.stopImmediatePropagation()
console.log(e.currentTarget.tagName)
}
p.addEventListener("click", consoleFunc, false)
div.addEventListener("click", consoleFunc, false)
p.addEventListener("click", function(){
console.log(111)
}, false)
</script>
</body>