stopPropagation против stopImmediatePropagation

Ответы:

321

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>

Обратите внимание, что здесь важен порядок привязки события!

Дейв
источник
1
Вы подчеркиваете «родитель», но в действительности оба также перестают вводить детей, если их вызывают на этапе захвата! Смотрите мой ответ для деталей.
Роберт Симер
57

Небольшой пример, чтобы продемонстрировать, как работают оба эти остановки распространения.

Есть три связанных обработчика событий. Если мы не остановим распространение, то должно быть четыре оповещения - три для дочернего элемента div и одно для родительского элемента div.

Если мы остановим распространение события, то будет 3 оповещения (все на внутреннем дочернем элементе div). Поскольку событие не распространяется по иерархии DOM, родительский div не увидит его, и его обработчик не сработает.

Если мы немедленно остановим распространение, то будет только 1 предупреждение. Несмотря на то, что к внутреннему дочернему элементу div прикреплены три обработчика событий, выполняется только 1, и любое дальнейшее распространение немедленно прекращается, даже внутри одного и того же элемента.

Анураг
источник
Оба stopPropagation()варианта также прекратят распространение по иерархии DOM. Не только вверх. Пожалуйста, проверьте мой ответ для деталей на этапе захвата.
Роберт Симер
26

Из API jQuery :

В дополнение к предотвращению выполнения любых дополнительных обработчиков на элементе, этот метод также останавливает всплывание, неявно вызывая event.stopPropagation (). Чтобы просто предотвратить всплытие события на элементы-предки, но разрешить выполнение других обработчиков событий для того же элемента, мы можем использовать event.stopPropagation ().

Используйте event.isImmediatePropagationStopped (), чтобы узнать, был ли когда-либо вызван этот метод (для этого объекта события).

Вкратце: event.stopPropagation()разрешает выполнение других обработчиков на том же элементе, в то же время event.stopImmediatePropagation()предотвращает запуск каждого события.

Арон Роттвил
источник
Просто чтобы быть уверенным, нативная версия javascript event.stopImmediatePropagationне перестает пузыриться, верно?
Александр Дерк
Это происходит, когда всплывающее сообщение происходит, когда событие распространяется на родительские элементы, stopImmediatePropagationостанавливает событие от периода распространения, оба они должны предотвращать всплывающее сообщение, ничего не стоит, что вы также можете изменить режим захвата, который будет запускать внешние элементы первым и только затем вниз к детям (пузыриться по умолчанию, и работает в направлении , противоположном)
JonnySerra
1
Не точно, если не сказать больше. Остановка на этапе захвата не позволит выполнять обработчики пузырьков на одном и том же элементе, как объяснено в моем ответе.
Роберт Симер
23

event.stopPropagationпредотвратит запуск обработчиков на родительских элементах.
Вызов event.stopImmediatePropagationтакже предотвратит запуск других обработчиков на том же элементе.

SLaks
источник
21
Стоит отметить, что обработчики событий выполняются в том порядке, в котором они были присоединены к элементу.
Феликс Клинг
19

Я опоздал, но, может быть, я могу сказать это на конкретном примере:

Скажем, если у вас есть <table>, с <tr>, а потом <td>. Теперь предположим, что вы установили 3 обработчика событий для <td>элемента, затем, если вы сделаете event.stopPropagation()первый обработчик событий, для которого вы установили <td>, все обработчики событий для по- <td>прежнему будут работать , но событие просто не будет распространяться на <tr>или <table>(и не будет идти и до <body>, <html>, documentи window).

Теперь, однако, если вы используете event.stopImmediatePropagation()в своем первом обработчике событий, то остальные два обработчика событий для <td>не будет работать , и не будет распространяться до <tr>, <table>(и не будет идти и до <body>, <html>, document, и window).

Обратите внимание, что это не только для <td>. Для других элементов это будет следовать тому же принципу.

nonopolarity
источник
10

1) event.stopPropagation(): => Используется только для остановки выполнения соответствующего родительского обработчика.

2) event.stopImmediatePropagation(): => Используется для остановки выполнения соответствующего родительского обработчика, а также обработчика или функции, прикрепленной к себе, кроме текущего обработчика. => Также останавливает весь обработчик, прикрепленный к текущему элементу всего DOM.

Вот пример: Jsfiddle !

Спасибо, -Сахил

Сахил Кашетвар
источник
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, который изменяет CSS, но в случае event.stopImmediatePropagation () следующее событие p щелчка не сработает.

Рахул Кумар
источник
2

Удивительно, но все остальные ответы говорят только половину правды или на самом деле неверны!

  • e.stopImmediatePropagation() останавливает вызов любого другого обработчика для этого события, без исключений
  • e.stopPropagation()аналогично, но все же вызывает все обработчики для этой фазы на этом элементе, если он еще не вызван

Какой этап?

Например, событие щелчка всегда будет сначала идти вниз по DOM (так называемая «фаза захвата»), в конце концов достигнет источника события («целевая фаза»), а затем снова всплывет («фаза пузыря»). И addEventListener()вы можете зарегистрировать несколько обработчиков для захвата и пузыря фазы независимо (Целевая фаза вызывает обработчики обоих типов на цели без различения.)

И это то, что другие ответы неверны:

  • цитата: «event.stopPropagation () позволяет выполнять другие обработчики на том же элементе»
  • исправление: если остановлено в фазе захвата, обработчики пузырьковой фазы никогда не будут достигнуты, также пропуская их на том же элементе
  • цитата: «event.stopPropagation () [...] используется, чтобы остановить выполнение только соответствующего родительского обработчика»
  • исправление: если остановлено в фазе захвата, обработчики на любых дочерних элементах, включая цель , также не вызываются, не только родители

Скрипка и mozilla.org фазы событий объяснения с демо.

Роберт Симер
источник
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>

Abhilash
источник