stopPropagation与stopImmediatePropagation

时间:2011-03-14 14:12:09

标签: javascript jquery

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

10 个答案:

答案 0 :(得分:278)

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

的处理程序

来自jquery documentation:

的快速示例

$("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>

答案 1 :(得分:50)

一个小例子来演示这些传播停止是如何工作的。

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,也只执行1个,并且即使在同一个元素内也会立即杀死任何进一步的传播。

答案 2 :(得分:27)

来自jQuery API

  

除了保留任何额外的   处理元素的处理程序   执行,这个方法也停止了   通过隐式调用冒泡   event.stopPropagation()。简单地说   防止事件冒泡到   祖先元素但允许其他元素   事件处理程序执行相同   元素,我们可以使用   event.stopPropagation()代替。

     

使用   event.isImmediatePropagationStopped()   知道这种方法是否曾经存在过   叫(在那个事件对象上)。

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

答案 3 :(得分:22)

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

答案 4 :(得分:16)

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

说,如果您有<table><tr>,然后<td>。现在,假设您为<td>元素设置了3个事件处理程序,然后如果您在为event.stopPropagation()设置的第一个事件处理程序中执行<td>,那么则为{{>}设置所有事件处理程序{1}}仍然会投放,但该事件不会传播到<td><tr>(并且不会上升到<table>,{{ 1}},<body><html>)。

但是,现在,如果您在第一个事件处理程序中使用document,则 window的其他两个事件处理程序将无法运行,并且不会传播最高为event.stopImmediatePropagation()<td>(并且不会上升到<tr><table><body><html>。< / p>

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

答案 5 :(得分:14)

令人惊讶的是,所有其他答案只说了一半真话或实际上是错的!

  • e.stopImmediatePropagation()停止为此事件调用任何进一步的处理程序,没有例外
  • e.stopPropagation()类似,但仍会在 this元素上调用 this phase 的所有处理程序,如果尚未调用

什么阶段?

例如点击事件始终会一直沿DOM一直下去(称为“捕获阶段”),最后到达事件的起点(“目标阶段”),然后再次冒泡(“泡沫阶段”)。使用addEventListener(),您可以为捕获和气泡阶段分别注册多个处理程序。 (目标阶段不区分而调用目标上这两种类型的处理程序。)

这是其他答案不正确的地方:

  • quote:“ event.stopPropagation()允许执行同一元素上的其他处理程序”
    • 更正:如果在捕获阶段停止,则气泡阶段处理程序将永远无法到达,还会在同一元素上跳过它们
  • quote:“ event.stopPropagation()[...]仅用于停止执行其相应的父处理程序”
    • 更正:如果在捕获阶段停止传播,则不会调用任何子级(包括目标)的处理程序,不仅是父级
    • ...并且:如果在气泡阶段停止传播,则已经调用了所有捕获阶段处理程序,包括在父级上的处理程序。

fiddle和mozilla.org event phase的演示说明。

答案 6 :(得分:8)

1)event.stopPropagation():  =&gt;它仅用于停止执行其相应的父处理程序。

2)event.stopImmediatePropagation():   =&GT;它用于停止执行其相应的父处理程序以及除当前处理程序之外附加到自身的处理程序或函数。   =&GT;它还会停止附加到整个DOM的当前元素的所有处理程序。

以下是示例:Jsfiddle

谢谢, -Sahil

答案 7 :(得分:4)

下面是一个演示差异的演示:

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>

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

答案 8 :(得分:3)

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 ,那么p元素上的下一个点击事件将会触发,但是如果 event.stopImmediatePropagation() ,下一个点击事件不会触发。

答案 9 :(得分:1)

这里我添加了我的JSfiddle示例,用于stopPropagation和stopImmediatePropagation。 JSFIDDLE

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>