事件冒泡和捕获之间的区别是什么?什么时候应该使用冒泡和捕获?
当前回答
冒泡
Event propagate to the upto root element is **BUBBLING**.
捕捉
Event propagate from body(root) element to eventTriggered Element is **CAPTURING**.
其他回答
If there are two elements element 1 and element 2. Element 2 is inside element 1 and we attach an event handler with both the elements lets say onClick. Now when we click on element 2 then eventHandler for both the elements will be executed. Now here the question is in which order the event will execute. If the event attached with element 1 executes first it is called event capturing and if the event attached with element 2 executes first this is called event bubbling. As per W3C the event will start in the capturing phase until it reaches the target comes back to the element and then it starts bubbling
捕获和冒泡状态是通过addEventListener方法的useCapture参数知道的
eventTarget.addEventListener(类型、侦听器(useCapture]);
默认情况下useCapture为false。这意味着它处于冒泡阶段。
var div1 = document.querySelector("#div1"); var div2 = document.querySelector("#div2"); div1。addEventListener(“点击”,函数(事件){ 警报(“您点击了div 1”); },真正的); div2。addEventListener(“点击”,函数(事件){ 警报(“您点击了div 2”); },假); # div1 { 背景颜色:红色; 填充:24 px; } # div2 { 背景颜色:绿色; } < div id = " div1 " > div 1 < div id = " div2 " > div 2 < / div > < / div >
请试着改变真假。
DOM Events描述了事件传播的3个阶段:捕获阶段——事件向下到元素。目标阶段——事件到达目标元素。冒泡阶段——事件从元素冒泡。
当浏览器检测到事件时,它会尝试查找事件处理程序。这个过程有三个阶段。假设我们有这些元素
<body>
<div>
<button>click</button>
</div>
</body>
1-Capture阶段
browser is going to take a look at the element that was just clicked. Then it will go to the top parent element which is body. if there is any click handle in body, the browser will call it. after checking the body element, it will look at the second top parent element which is div element. This process will repeat until the browser gets down to the button element at the very bottom. Once it sees the button element, Phase One- Capturing will be over. Most of the time we ignore this phase. This code ignores this phase
document.addEventListener('click',handleClick)
如果你想涉及到这一阶段,你必须这样写
document.addEventListener('click',handleClick,true)
当我们需要检测目标之外的点击时,我们就需要这个阶段。也许我们有一个打开的下拉菜单或者模态菜单如果用户点击了模态菜单或者下拉菜单之外的任何地方,我们想要关闭它
2-Target阶段
浏览器会查看被点击的按钮元素,如果按钮有事件处理程序,浏览器会调用它。
3-气泡阶段
与捕获阶段相反,在这个阶段,浏览器将从直接的父元素(在这种情况下是div元素)开始这个过程,然后它将访问body元素。这段代码将为气泡阶段设置事件处理程序
document.addEventListener('click',handleClick,false)
事件冒泡和捕获是HTML DOM API中事件传播的两种方式,当一个事件发生在另一个元素中的元素中,并且两个元素都为该事件注册了句柄。事件传播模式决定元素接收事件的顺序。
使用冒泡,事件首先由最内部的元素捕获和处理,然后传播到外部元素。
通过捕获,事件首先由最外层的元素捕获并传播到内部元素。
捕捉也被称为“涓滴”,这有助于记住传播顺序:
涓滴而下,泡沫而起
在过去,Netscape提倡事件捕获,而微软则提倡事件冒泡。两者都是W3C文档对象模型事件标准(2000)的一部分。
IE < 9只使用事件冒泡,而IE9+和所有主流浏览器都支持这两种方式。另一方面,对于复杂的dom,事件冒泡的性能可能略低。
我们可以使用addEventListener(type, listener, useCapture)以冒泡(默认)或捕获模式注册事件处理程序。要使用捕获模型,将第三个参数传递为true。
例子
<div>
<ul>
<li></li>
</ul>
</div>
在上面的结构中,假设li元素中发生了单击事件。
在捕获模型中,事件将首先由div处理(在div中单击事件处理程序将首先触发),然后是ul,最后是目标元素li。
在冒泡模型中,将发生相反的情况:事件将首先由li处理,然后由ul处理,最后由div元素处理。
有关更多信息,请参见
QuirksMode上的事件顺序 addEventListener在MDN QuirksMode上的高级事件
在下面的示例中,如果单击任何突出显示的元素,可以看到事件传播流的捕获阶段首先发生,然后是冒泡阶段。
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); 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; } <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>
JSFiddle的另一个例子。
正如其他人所说,冒泡和捕获描述了一些嵌套元素接收给定事件的顺序。
我想指出,对于最里面的元素可能会出现一些奇怪的东西。实际上,在这种情况下,添加事件侦听器的顺序确实很重要。
在下面的例子中,捕获div2将先执行,然后再执行冒泡;当为div4冒泡时,将先执行而不是捕获。
function addClickListener (msg, num, type) { document.querySelector("#div" + num) .addEventListener("click", () => alert(msg + num), type); } bubble = (num) => addClickListener("bubble ", num, false); capture = (num) => addClickListener("capture ", num, true); // first capture then bubble capture(1); capture(2); bubble(2); bubble(1); // try reverse order bubble(3); bubble(4); capture(4); capture(3); #div1, #div2, #div3, #div4 { border: solid 1px; padding: 3px; margin: 3px; } <div id="div1"> div 1 <div id="div2"> div 2 </div> </div> <div id="div3"> div 3 <div id="div4"> div 4 </div> </div>
编辑:这种行为可能因浏览器而异(例如,目前在Firefox上出现,但在Chrome和Edge上没有)。然而,我认为人们应该意识到这一点。
推荐文章
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期
- Javascript复选框onChange
- Javascript函数前导bang !语法
- 如何在页面上遍历所有DOM元素?
- 在JS/jQuery中触发按键/按键/按键事件?
- 如何每5秒重新加载页面?