stopPropagation vs. stopImmediatePropagation

event.stopPropagation()event.stopImmediatePropagation()之间有什么区别?

147482 次浏览

event.stopPropagation将阻止父元素上的处理程序运行 调用event.stopImmediatePropagation还将阻止同一元素上的其他处理程序运行

jQuery API:

除了保留任何额外的 元素的处理程序 执行后,此方法还将停止 通过隐式调用 event.stopPropagation()。简单地 防止事件冒泡到 祖先元素但允许其他元素 执行相同的事件处理程序 元素,我们可以使用 event.stopPropagation()。< / p > < p >使用 event.isImmediatePropagationStopped () 想知道这种方法是否曾经

.调用(在该事件对象上)

简而言之:event.stopPropagation()允许同一元素上的其他处理程序被执行,而event.stopImmediatePropagation()阻止每一个事件运行。

stopPropagation将阻止任何处理程序被执行stopImmediatePropagation将阻止任何父处理程序任何其他处理程序被执行

来自jquery文档:的快速示例

$("p").click(function(event) {
event.stopImmediatePropagation();
});


$("p").click(function(event) {
// This function won't be executed
$(this).css("background-color", "#f00");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p>example</p>

注意,事件绑定的顺序在这里很重要!

$("p").click(function(event) {
// This function will now trigger
$(this).css("background-color", "#f00");
});


$("p").click(function(event) {
event.stopImmediatePropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p>example</p>

一个演示这两种传播停止如何工作的小示例。

var state = {
stopPropagation: false,
stopImmediatePropagation: false
};


function handlePropagation(event) {
if (state.stopPropagation) {
event.stopPropagation();
}


if (state.stopImmediatePropagation) {
event.stopImmediatePropagation();
}
}


$("#child").click(function(e) {
handlePropagation(e);
console.log("First event handler on #child");
});




$("#child").click(function(e) {
handlePropagation(e);
console.log("Second event handler on #child");
});


// First this event will fire on the child element, then propogate up and
// fire for the parent element.
$("div").click(function(e) {
handlePropagation(e);
console.log("Event handler on div: #" + this.id);
});




// Enable/disable propogation
$("button").click(function() {
var objectId = this.id;
$(this).toggleClass('active');
state[objectId] = $(this).hasClass('active');
console.log('---------------------');
});
div {
padding: 1em;
}


#parent {
background-color: #CCC;
}


#child {
background-color: #000;
padding: 5em;
}


button {
padding: 1em;
font-size: 1em;
}


.active {
background-color: green;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<div id="child">&nbsp;</div>
</div>


<button id="stopPropagation">Stop Propogation</button>
<button id="stopImmediatePropagation" ">Stop Immediate Propogation</button>

绑定了三个事件处理程序。如果我们不停止任何传播,那么应该有四个警报——三个在子div上,一个在父div上。

如果我们停止事件传播,那么将会有3个警报(都在内部子div上)。由于事件不会沿着DOM层次结构向上传播,所以父div不会看到它,它的处理程序也不会触发。

如果我们立即停止传播,那么只有1个警报。尽管有三个事件处理程序附加到内部的子div,但只执行了一个,并且立即终止任何进一步的传播,即使是在同一元素中。

event.stopPropagation ()允许同一元素上的其他处理程序被执行,而event.stopImmediatePropagation ()阻止每个事件运行。例如下面的jQuery代码块。

$("p").click(function(event)
{ event.stopImmediatePropagation();
});
$("p").click(function(event)
{ // This function won't be executed
$(this).css("color", "#fff7e3");
});

如果在前面的例子中使用了event.stopPropagation,则更改css的p元素上的下一个单击事件将触发,但如果是event.stopImmediatePropagation (),则下一个p单击事件将不会触发。

我是一个后来者,但也许我可以用一个具体的例子来说明:

比如,如果你有一个<table>,带有<tr>,然后是<td>。现在,让我们假设你为<td>元素设置了3个事件处理程序,然后如果你在为<td><tr>3设置的第一个事件处理程序中执行event.stopPropagation(),但事件不会传播到<tr><table>(并且不会不断上升到<body><tr>0, <tr>1和<tr>2)。

然而,现在,如果你在你的第一个事件处理程序中使用event.stopImmediatePropagation(),那么,<td>的其他两个事件处理程序将不会运行,并且不会向上传播到<tr><table>(并且不会向上传播到<body><html>documentwindow)。

注意,它不仅仅适用于<td>。对于其他元素,它将遵循相同的原则。

< p > 1) event.stopPropagation(): =>仅用于停止相应父处理程序的执行 < p > 2) event.stopImmediatePropagation(): 它用于停止其相应的父处理程序的执行,也用于停止除当前处理程序外附加到自身的处理程序或函数的执行。 它还会停止所有附加到整个DOM的当前元素的处理程序

下面是示例:Jsfiddle!

< p >谢谢, sahil聊< / p >
这里我添加了stopPropagation vs stopImmediatePropagation的JSfiddle示例。 JSFIDDLE < / p >

let stopProp = document.getElementById('stopPropagation');
let stopImmediate = document.getElementById('stopImmediatebtn');
let defaultbtn = document.getElementById("defalut-btn");




stopProp.addEventListener("click", function(event){
event.stopPropagation();
console.log('stopPropagation..')
  

})
stopProp.addEventListener("click", function(event){
console.log('AnotherClick')
  

})
stopImmediate.addEventListener("click", function(event){
event.stopImmediatePropagation();
console.log('stopimmediate')
})


stopImmediate.addEventListener("click", function(event){
console.log('ImmediateStop Another event wont work')
})


defaultbtn.addEventListener("click", function(event){
alert("Default Clik");
})
defaultbtn.addEventListener("click", function(event){
console.log("Second event defined will also work same time...")
})
div{
margin: 10px;
}
<p>
The simple example for event.stopPropagation and stopImmediatePropagation?
Please open console to view the results and click both button.
</p>
<div >
<button id="stopPropagation">
stopPropagation-Button
</button>
</div>
<div  id="grand-div">
<div class="new" id="parent-div">
<button id="stopImmediatebtn">
StopImmediate
</button>
</div>
</div>
<div>
<button id="defalut-btn">
Normat Button
</button>
</div>

令人惊讶的是,all其他答案只说了一半事实或实际上是错误的!

  • e.stopImmediatePropagation()停止为此事件调用任何进一步的处理程序,没有异常
  • e.stopPropagation()类似,但如果尚未调用,仍然调用这个元素这一阶段的所有处理程序

什么阶段?

例如,一个点击事件总是首先沿着DOM向下走(称为“捕获阶段”),最后到达事件的起源(“目标阶段”),然后再次冒泡(“冒泡阶段”)。使用addEventListener(),你可以分别为捕获阶段和冒泡阶段注册多个处理程序。(目标阶段在目标上调用这两种类型的处理程序,没有区别。)

这是其他答案的错误之处:

  • quote: " event.stopPropagation()允许同一元素上的其他处理程序被执行"
    • 纠正:如果在捕获阶段停止,气泡阶段处理程序将永远不会到达,在同一元素上跳过它们
  • quote: " event.stopPropagation()[…]]仅用于停止相应父处理程序的执行。
    • 更正:如果传播在捕获阶段停止,则任何儿童,包括目标上的处理程序也不会被调用,而不仅仅是父类
    • ...并且:如果在气泡阶段停止传播,则所有捕获阶段处理程序都已被调用,包括父阶段处理程序

A < A href="https://jsfiddle.net/siemer/3qfo57zj/17/" rel="noreferrer">小提琴和mozilla.org < A href="https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase" rel="noreferrer">事件阶段解释与演示。

下面是一个演示来说明两者的区别:

document.querySelectorAll("button")[0].addEventListener('click', e=>{
e.stopPropagation();
alert(1);
});
document.querySelectorAll("button")[1].addEventListener('click', e=>{
e.stopImmediatePropagation();
alert(1);
});
document.querySelectorAll("button")[0].addEventListener('click', e=>{
alert(2);
});
document.querySelectorAll("button")[1].addEventListener('click', e=>{
alert(2);
});
<div onclick="alert(3)">
<button>1...2</button>
<button>1</button>
</div>

请注意,可以将多个事件处理程序附加到元素上的事件。