目录
1、dom 事件流
事件流是指当事件发生时,会在发生事件的元素节点与DOM树根节点之间按照特定的顺序进行传播,这个过程称之为事件流。
网景(Netscape)公司团队的事件流采用事件捕获方式,而微软(Microsoft)公司的事件流采用事件冒泡方式,W3C对网景公司和微软公司提出的方案进行了中和处理,规定了事件发生后,首先实现事件捕获,但不会对事件进行处理;然后进行到目标阶段,执行当前元素对象的事件处理程序,但它会被看成是冒泡阶段的一部分;最后实现事件的冒泡,逐级对事件进行处理。
W3C规定的事件流的具体过程对比如下图所示:
js的事件捕获和事件冒泡发生在dom节点绑定事件触发的过程中,事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件,事件捕获和事件冒泡属于两个相反的过程。
一般的,事件分为三个阶段:捕获阶段、目标阶段和冒泡阶段。
(1)捕获阶段
事件从文档的根节点流向目标对象节点,途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。
(2)目标阶段
当事件到达目标节点时,事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的根节点。
(3)冒泡阶段
事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播。
示例代码:
2、事件冒泡
单击页面中的<div>
元素,事件会按照如下顺序传播:
<div>
<body>
<html>
document
<div class="father">
<div class="son"></div>
</div>
<script>
var father=document.querySelector('.father');
var son=document.querySelector('.son');
father.onclick=function(){
console.log('父盒子');
}
son.onclick=function(){
console.log('子盒子');
}
</script>
蓝色的大盒子是父盒子,绿色的小盒子是子盒子
当你点击son盒子,son在father里面,所以点击son时,也同时点击了father,这就是事件冒泡
3、事件捕获
网景公司提出的事件流叫事件捕获流。
单击页面中的<div>
元素,事件会按照如下顺序传播:
document
<html>
<body>
<div>
正如我们看到的,和冒泡流万全相反,从最不具体的元素接收到最具体的元素接收事件
4、阻止事件冒泡
方法一:在相应的函数中加上event.stopPropagation()
//event.stopPropagation()
<script>
var father=document.querySelector('.father');
var son=document.querySelector('.son');
father.onclick=function(){
console.log('父盒子');
event.stopPropagation()
}
son.onclick=function(){
console.log('子盒子');
event.stopPropagation()
}
</script>
此时,你点击子盒子
方法二:判断event.target 和 event.currentTarget是否相等
event.target:指真正触发事件的元素
event.currentTarget:指绑定了事件监听的元素(触发事件元素的父级元素)
这时判断两者相等,则执行相应的处理函数;当事件冒泡到上一级时,event.currentTarget变成 了上一级元素,这时候判断二者不相等,则就不作响应处理逻辑。
//event.target
<script>
var father=document.querySelector('.father');
var son=document.querySelector('.son');
father.onclick=function(){
if(event.target==event.currentTarget){
console.log('父盒子');
}
}
son.onclick=function(){
if (event.target == event.currentTarget) {
console.log('子盒子');
}
}
</script>
此时,你点击子盒子