事件捕获、事件冒泡详解

问题:如果三个嵌套的div(div100>div10>div1),每个div都绑定了方法,那点击div1触发方法的顺序如何?

介绍:W3C标准的浏览器(非IE)中,JS的执行会经历三个阶段:捕获阶段目标阶段冒泡阶段。这三个阶段成为JS执行的事件流

默认规则:JS的事件一般都是在冒泡阶段触发执行

词汇:Bubble(冒泡),Capture(捕获),propagation(传播)。

答案:点击div1,方法执行顺序一般是div1->div10->div100。(如果存在监听函数addEventListeren,让父级元素在捕获阶段执行,则执行顺序不同。)

起航:浏览器的事件流(如图1所示)


图1 浏览器事件流机制

例子1:正常情况(冒泡阶段

//HTML代码
<div class="div100" οnclick="alert('div100->Bubble')"> //父父级
    <div class="div10" οnclick="alert('div10->Bubble')"> //父级
        <div class="div1" οnclick="alert('div1->Bubble')"> //子级
            点击
        </div>
    </div>
</div>
//CSS代码
.div100{
    width: 300px;
    height: 300px;
    margin: 0 auto;
    padding: 100px;
    background-color: #aaa;
}
.div10{
    width: 100px;
    height: 100px;
    padding: 100px;
    background-color: #ccc;
}
.div1{
    width: 100px;
    height: 100px;
    background-color: #eee;
    text-align: center;
    line-height: 100px;
    cursor: pointer;
    color: #888;
}

执行顺序:alert('div1->Bubble')->alert('div10->Bubble')->alert('div100->Bubble')。

原因:在点击div1时,浏览器JS开始进入捕获流,寻找是否存在捕获阶段需要执行的方法,由于不存在,而方法都默认在冒泡阶段执行,所以执行顺序如上述。


例子2:在例子1的情况下,追加下列JS代码。(捕获阶段

window.onload = function(){
    var div100 = document.getElementsByClassName('div100')[0];
    div100.addEventListener('click', function(){alert('div100->Capture')}, true); //('事件','方法','是否捕获')
}

执行顺序:alert('div100->Capture')->alert('div1->Bubble')->alert('div10->Bubble')->alert('div100->Bubble')。

原因:在点击div1时,浏览器JS开始进入捕获流,寻找是否存在捕获阶段需要执行的方法,由于存在div100的捕获阶段需要执行的方法,执行完div100捕获的方法,再依次执行冒泡阶段的方法,所以执行顺序如上述。


例子3:在例子1的情况下,追加下列JS代码。(目标阶段

window.onload = function(){
    var div100 = document.getElementsByClassName('div100')[0];
    var div10 = document.getElementsByClassName('div10')[0];
    var div1 = document.getElementsByClassName('div1')[0];
    div100.addEventListener('click', function(){alert('div100->Capture')}, true);
    div10.addEventListener('click', function(){alert('div10->Capture')}, true);
    div1.addEventListener('click', function(){alert('div1->Capture')}, true);
}

执行顺序:

alert('div100->Capture')->alert('div10->Capture')->alert('div1->Bubble')->

alert('div1->Capture')->alert('div10->Bubble')->alert('div100->Bubble')。

原因:

1.在点击div1时,浏览器JS开始进入捕获流,执行完div100和div10的捕获方法后。

2.进入目标阶段,该阶段则根据方法的编写先后执行,由于window.onload是在html代码编写完再编写,所以alert('div1->Bubble')先于alert('div1->Capture')执行。

3.依次执行冒泡阶段函数。div10和div100的冒泡方法。


误区:event.stopPropagation

JQ解释:防止事件冒泡到DOM树上,也就是不触发的任何前辈元素上的事件处理函数。

个人见解:防止事件传播,所以当执行stopPropagation后,就不会继续传播事件,也就是捕获阶段,目标阶段,冒泡阶段都可能被阻止。


推荐阅读:

vue2.0数据更新,重新渲染视图的三种方法

JS将数字转成货币形式的简单方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值