首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是事件冒泡和捕获?

什么是事件冒泡和捕获?
EN

Stack Overflow用户
提问于 2011-01-06 23:44:43
回答 8查看 477K关注 0票数 1.2K

事件冒泡和捕获有什么区别?什么时候应该使用冒泡vs捕获?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-01-06 23:47:05

事件冒泡和捕获是HTML DOM API中事件传播的两种方式,当一个事件发生在另一个元素内的一个元素中时,这两个元素都为该事件注册了一个句柄。事件传播模式在which order the elements receive the event中确定。

对于冒泡,事件首先由最里面的元素捕获和处理,然后传播到外部元素。

使用捕获时,事件首先由最外层的元素捕获,并传播到内部元素。

捕获也被称为“滴流”,它有助于记住传播顺序:

往下滴,往上冒

回到过去,Netscape提倡事件捕获,而微软则提倡事件冒泡。两者都是W3C Document Object Model Events标准(2000)的一部分。

IE <9使用only event bubbling,而IE9+和所有主流浏览器都支持这两种浏览器。另一方面,复杂DOM的performance of event bubbling may be slightly lower

我们可以使用addEventListener(type, listener, useCapture)在冒泡(默认)或捕获模式下注册事件处理程序。要使用捕获模型,请将第三个参数作为true传递。

示例

代码语言:javascript
复制
<div>
    <ul>
        <li></li>
    </ul>
</div>

在上面的结构中,假设在li元素中发生了一个单击事件。

在捕获模型中,事件将首先由div处理(单击div中的事件处理程序将首先触发),然后在ul中,然后在目标元素li中的最后。

在冒泡模型中,将发生相反的情况:事件将首先由li处理,然后由ul处理,最后由div元素处理。

有关详细信息,请参阅

在下面的示例中,如果您单击任何突出显示的元素,您可以看到事件传播流的捕获阶段首先发生,然后是冒泡阶段。

代码语言:javascript
复制
var logElement = document.getElementById('log');

function log(msg) {
    logElement.innerHTML += ('<p>' + msg + '</p>');
}

function capture() {
    log('capture: ' + this.firstChild.nodeValue.trim());
}

function bubble() {
    log('bubble: ' + this.firstChild.nodeValue.trim());
}

function clearOutput() {
    logElement.innerHTML = "";
}

var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
    divs[i].addEventListener('click', capture, true);
    divs[i].addEventListener('click', bubble, false);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
代码语言:javascript
复制
p {
    line-height: 0;
}

div {
    display:inline-block;
    padding: 5px;

    background: #fff;
    border: 1px solid #aaa;
    cursor: pointer;
}

div:hover {
    border: 1px solid #faa;
    background: #fdd;
}
代码语言:javascript
复制
<div>1
    <div>2
        <div>3
            <div>4
                <div>5</div>
            </div>
        </div>
    </div>
</div>
<button id="clear">clear output</button>
<section id="log"></section>

Another example at JSFiddle

票数 1.6K
EN

Stack Overflow用户

发布于 2011-01-06 23:46:18

描述:

对此有一个很好的描述。简而言之(从quirksmode复制):

事件捕获

当您使用事件捕获时

|-||-| element1 |-|- |element2 \/||-- ||事件捕获|

element1的事件处理程序首先触发,element2的事件处理程序最后触发。

事件冒泡

使用事件冒泡时

/\-||-| element1 |-|- |element2 |-||事件冒泡|

element2的事件处理程序首先触发,element1的事件处理程序最后触发。

要使用什么?

这取决于你想做什么。没有比这更好的了。不同之处在于事件处理程序的执行顺序。大多数情况下,在冒泡阶段触发事件处理程序是可以的,但也有必要提前触发它们。

票数 543
EN

Stack Overflow用户

发布于 2014-03-04 20:45:51

如果有两个元素,元素1和元素2。元素2在元素1中,我们用这两个元素附加一个事件处理程序,假设是onClick。现在,当我们单击元素2时,这两个元素的eventHandler都将被执行。现在这里的问题是事件将以什么顺序执行。如果与元素1关联的事件首先执行,则称为事件捕获;如果与元素2关联的事件首先执行,则称为事件冒泡。根据W3C,事件将在捕获阶段开始,直到它到达目标,返回到元素,然后开始冒泡

捕获和冒泡状态由addEventListener方法的useCapture参数获知

eventTarget.addEventListener(类型,监听器,,useCapture);

默认情况下,useCapture为false。这意味着它正处于冒泡阶段。

代码语言:javascript
复制
var div1 = document.querySelector("#div1");
var div2 = document.querySelector("#div2");

div1.addEventListener("click", function (event) {
  alert("you clicked on div 1");
}, true);

div2.addEventListener("click", function (event) {
  alert("you clicked on div 2");
}, false);
代码语言:javascript
复制
#div1{
  background-color:red;
  padding: 24px;
}

#div2{
  background-color:green;
}
代码语言:javascript
复制
<div id="div1">
  div 1
  <div id="div2">
    div 2
  </div>
</div>

请尝试更改true和false。

票数 77
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4616694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档