事件冒泡

作者: 没名字的某某人 | 来源:发表于2021-07-27 11:21 被阅读0次

事件冒泡

微软提出的事件流叫事件冒泡,也就是说事件的传播为:从事件开始的具体元素,一级级往上传播到较为不具体的节点。案例如下:

<div id="outer">
    <p id="inner">Click me!</p> 
</div>

当我们点击P元素时,事件是这样传播的:

  • p
  • div
  • body
  • html
  • document
    现代浏览器都支持事件冒泡

事件捕获

网景团队提出的另一种事件流叫做事件捕获。它的原理刚好和事件冒泡相反,它的用意在于事件到达预定目标之前捕获它,而最具体的节点应该是最后才接收到事件的。
比如上面的案例,事件的传播方向就变成了这样:

  • document
  • html
  • body
  • div
  • p
    目前主流浏览器也支持这种事件流模型,但是老版本浏览器不支持,所以很少人使用事件捕获,而是用事件冒泡多一点。

DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
首先发生的事件捕获,为截获事件提供机会。然后是实际的目标接受事件。最后一个阶段是事件冒泡阶段,可以在这个阶段对事件作出相应。以前面的例子,则会按下图顺序触发事件。



在DOM事件流中,事件的目标在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从document到p后就停止了

下一个阶段是处于目标阶段,于是事件在p上发生,并在事件处理中被看成冒泡阶段的一部分。然后冒泡阶段发生。

多数支持DOM事件流的浏览器都实现了一种特定的行为;即使“DOM2级事件”规范明确要求捕获阶段不会涉及事件目标,但浏览器都会在捕获阶段触发事件对象上的事件。结果就是有两个机会在目标对象上操作事件。

addEventListener 的第三个参数

“DOM2级事件”中规定的事件流同时支持了事件捕获阶段和事件冒泡阶段,而作为开发者,我们可以选择事件处理函数在哪一个阶段被调用。

addEventListener方法用来为了一个特定的元素绑定一个事件处理函数,是js中常用的方法。addEventListener有三个参数:

element.addEventListener(event, function, useCapture)

事件代理

在实际的开发中,利用事件流的特性,我们可以使用一种叫做事件代理的方法。

<ul class="color_list">        
    <li>red</li>        
    <li>orange</li>        
    <li>yellow</li>        
    <li>green</li>        
    <li>blue</li>        
    <li>purple</li>    
</ul>
<div class="box"></div>
.color_list{            
    display: flex;            
    display: -webkit-flex;        
}        
.color_list li{            
    width: 100px;            
    height: 100px;            
    list-style: none;            
    text-align: center;            
    line-height: 100px;        
}
//每个li加上对应的颜色,此处省略
.box{            
    width: 600px;            
    height: 150px;            
    background-color: #cccccc;            
    line-height: 150px;            
    text-align: center;        
}

我们想要点击每个li标签时,输出li当中的颜色(innerHTML)。常规做法是遍历每个li,然后在每个li上绑定一个点击事件:

var color_list=document.querySelector(".color_list");            
var colors=color_list.getElementsByTagName("li");            
var box=document.querySelector(".box");            
for(var n=0;n<colors.length;n++){                
    colors[n].addEventListener("click",function(){                    
        console.log(this.innerHTML)                    
        box.innerHTML="该颜色为 "+this.innerHTML;                
    })            
}

这种做法在li较少的时候用可以使用,加入很多个li就会导致降低性能。
这时就需要事件代理出场了,利用事件流的特性,我们只绑定一个事件处理函数也可以完成:

function colorChange(e){                
    var e=e||window.event;//兼容性的处理         
    if(e.target.nodeName.toLowerCase()==="li"){                    
        box.innerHTML="该颜色为 "+e.target.innerHTML;                
    }                            
}            
color_list.addEventListener("click",colorChange,false)

由于事件冒泡机制,点击了li后悔冒泡到ul,此时就会触发绑定在ul上的点击事件,再利用target找到事件实际发生的元素,就可以达到预期的效果。

使用事件代理的好处不仅在于将多个事件处理函数减为一个,而且对于不同的元素可以有不同的处理方法。加入上述列表当中添加了其他的元素节点,我们不必再一次循环给每个元素绑定事件。

冒泡还是捕获?

对于事件代理来说,在时间捕获或者事件冒泡阶段处理并没有明显的优劣之分,但是由于事件冒泡的事件流模型被所有主流的浏览器兼容,从兼容性角度还是推荐事件冒泡模型。

阻止事件冒泡和阻止默认事件

$("#div1").mousedown(function(e){
    var e=event||window.event;
    event.stopPropagation();
});

event.preventDefault( )

相关文章

  • 微信小程序中bind和catch的区别

    bindtap 冒泡事件,事件绑定不会阻止冒泡事件向上冒泡catchtap 非冒泡事件, 事件绑定阻止冒泡事件...

  • 事件绑定 和 方法传值

    冒泡和非冒泡事件绑定 bindtap: 冒泡事件绑定 catchtap: 非冒泡事件绑定当其他的事件冒泡到当前元素...

  • wepy基础知识

    1、bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。https://deve...

  • 微信小程序 WXML事件 WXML冒泡事件列表

    WXML事件分为 冒泡事件 和 非冒泡事件。 冒泡事件:当一个事件被触发后,该事件会向父节点传递。 非冒泡事件:不...

  • 小程序冒泡事件

    冒泡事件列表 解决冒泡事件

  • 什么是事件冒泡/捕获?

    事件冒泡:子元素事件的触发会影响父元素事件开关事件冒泡:A:开启事件冒泡:element.addEventList...

  • 小程序中点击子元素事件而不触发父元素的点击事件

    原理:bind事件绑定不会阻止冒泡事件向上冒泡catch事件绑定可以阻止冒泡事件向上冒泡 当点击子元素的catch...

  • vue中的事件

    单击事件:@click=" " 事件对象:@click="show($event)" 事件冒泡: 阻止冒泡事件:@...

  • JavaScript中的冒泡事件

    事件冒泡机制 事件冒泡发生的条件:当为多个嵌套的元素设置了相同的事件处理程序,它们将触发事件冒泡机制。在事件冒泡中...

  • 阻止事件冒泡

    什么是事件冒泡? 要知道怎么阻止事件冒泡,首先我们来看一下什么是事件冒泡。 事件冒泡即在一个对象上触发某类事件(比...

网友评论

    本文标题:事件冒泡

    本文链接:https://www.haomeiwen.com/subject/qjznmltx.html