stopPropagation vs. 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

Невеликий приклад продемонструвати, як працюють обидва ці зупинки розповсюдження.

Зв'язано три обробники подій. Якщо ми не припиняємо жодного розповсюдження, то повинно бути чотири сповіщення - три на дочірньому діві та одне на батьківському діві.

Якщо ми припинимо поширювати подію, то надійде три сповіщення (усі про внутрішню дітлаху). Оскільки подія не поширюватиметься на ієрархію DOM, батьківський div не побачить її, і її обробник не запустить.

Якщо ми припинимо розповсюдження негайно, то буде лише 1 попередження. Незважаючи на те, що до внутрішнього дочірнього діви є три обробники подій, лише 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також не дозволить іншим обробникам цього ж елемента працювати.


21
Варто згадати, що обробники подій виконуються в тому порядку, в якому вони були прикріплені до елемента.
Фелікс Клінг

18

Я пізній учасник, але, можливо, можу сказати це на конкретному прикладі:

Скажіть, якщо у вас є <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>. Для інших елементів він буде дотримуватися того самого принципу.


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 vs 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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.