捕获与冒泡

165 阅读2分钟

事件的分发顺序,div.grandpa,div.father,div.child 在屏幕上的区域一样,点击屏幕时,会同时触发这三个节点的点击事件 那么,这三个节点按照什么顺序响应点击顺序呢? 爷父子,这个顺序响应,叫做,事件捕获 子父爷,这个顺序响应,叫做,事件冒泡 W3C规定,按照,先处理事件捕捉,后处理事件冒泡,也就是处理顺序是爷父子,子父爷,顺序响应

div.addEventListener("click",fn(),true),这是事件捕捉模式
div.addEventListener("click",fn()),这是事件冒泡模式
<div class="grandpa">
    <div class="father">
        <div class="child">
            文字
        </div>
    </div>
</div>
$('.grandpa').click(function (){
    console.log("爷爷被点击了");
})
$('.father').click(function (){
    console.log("父亲被点击了");
});
$('.child').click(()=>{
    console.log("孩子被点击了");
});

帮助巩固理解事件捕捉和事件冒泡极好的例子js.jirengu.com/tulin/3/edi…

从这个代码例子可以看出: 1 JS先处理事件捕捉,再处理事件冒泡,没有特例 2 事件捕捉时,先从最外层开始 3 事件冒泡时,先从最里层开始 4 事件冒泡时,事件可以在处理时被拦截,e.stopPropagation(),不再向父亲传递 5 冒泡拦截时,只能拦截事件不向父亲传递,此节点的这一次点击事件,该怎么执行还是怎么执行,后面的代码还是要执行

let n = 1;
const divs = Array.from(document.querySelectorAll('.circle'));
divs.map((node)=>{node.classList.remove('x')});
divs.map((node)=>{
    // w3c规定,先处理事件捕捉,再处理事件冒泡,没有特例
    node.addEventListener("click", function (e){
        let eventTarget = e.currentTarget;
        console.log("n0="+n);
        setTimeout(()=>{
            eventTarget.classList.add('x');
        },  n*1000)
        n = n>=14 ? 1 : n+1;
    },true); //事件捕捉 ,先从父开始,最外面的圆最先消失
    node.addEventListener("click", function (e){
        let eventTarget = e.currentTarget;
        setTimeout(()=>{
            eventTarget.classList.remove('x');
        },n*1000)
        n = n>=14 ? 1 : n+1;
    }); // 冒泡,先从子开始,最里面的圆最先着色
});
<div class="circle red">
    <div class="circle orange">
        <div class="circle yellow">
            <div class="circle green">
                <div class="circle cyan">
                    <div class="circle blue">
                        <div class="circle purple">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
.circle{
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
}
.red{
    width: 210px;
    height: 210px;
    background-color: red;
}
.orange{
    width: 180px;
    height: 180px;
    background-color: orange;
}
.yellow{
    width: 150px;
    height: 150px;
    background-color: yellow;
}
.green{
    width: 120px;
    height: 120px;
    background-color: green;
}
.cyan{
    width: 90px;
    height: 90px;
    background-color: cyan;
}
.blue{
    width: 60px;
    height: 60px;
    background-color: blue;
}
.purple{
    width: 30px;
    height: 30px;
    background-color: purple;
}
.x{
    background-color: white;
}