Какая разница между event.stopPropagation и event.preventDefault?

Они, похоже, делают то же самое... Один современный и старый? Или они поддерживаются разными браузерами?

Когда я обрабатываю события самостоятельно (без фреймворка), я всегда проверяю оба и выполняю оба, если они есть. (Я также return false, но я чувствую, что не работает с событиями, связанными с node.addEventListener).

Так почему же? Должен ли я продолжать проверять оба? Или есть ли разница?

(Я знаю, много вопросов, но все они одинаковы =))

Ответ 1

stopPropagation останавливает всплытие события в цепочке событий.

preventDefault запрещает действие по умолчанию, которое браузер выполняет с этим событием.

Примеры

preventDefault

$("#but").click(function (event) {
  event.preventDefault()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

Ответ 2

терминология

С quirksmode.org:

Захват событий

Когда вы используете захват событий

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

обработчик события element1 срабатывает первым, обработчик события element2 срабатывает последним.

Событие кипит

Когда вы используете всплывающее событие

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

обработчик события element2 срабатывает первым, обработчик события element1 срабатывает последним.

Любое событие, происходящее в модели событий W3C, сначала фиксируется до достижения целевого элемента, а затем снова всплывает.

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

Интерфейс

С w3.org, для захвата событий:

Если захват EventListener желает предотвратить дальнейшую обработку события, он может вызвать метод stopPropagation интерфейса Event. Это предотвратит дальнейшую отправку события, хотя дополнительные EventListeners зарегистрированные на том же уровне иерархии, все еще получат событие. После stopPropagation метода stopPropagation дальнейшие вызовы этого метода не имеют никакого дополнительного эффекта. Если никаких дополнительных захватчиков не существует и stopPropagation не был вызван, событие вызывает соответствующие EventListeners на самой цели.

Для всплытия событий:

Любой обработчик события может решить предотвратить дальнейшее распространение события, вызвав метод stopPropagation интерфейса Event. Если какой-либо EventListener вызывает этот метод, все дополнительные EventListeners на текущем EventTarget будут запущены, но EventTarget прекратятся на этом уровне. Только один вызов stopPropagation требуется, чтобы предотвратить дальнейшее образование пузырьков.

Для отмены мероприятия:

Отмена осуществляется путем вызова метода Event preventDefault. Если один или несколько EventListeners вызовут preventDefault во время любой фазы потока событий, действие по умолчанию будет отменено.

Примеры

В следующих примерах щелчок по гиперссылке в веб-браузере запускает поток событий (слушатели событий выполняются) и целевое действие события по умолчанию (открывается новая вкладка).

HTML:

<div id="a">
  <a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>

JavaScript:

var el = document.getElementById("c");

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
}

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
}

function bubblingOnClick1(ev) {
    el.innerHTML += "DIV event bubbling<br>";
}

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
}

// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);

Пример 1: это приводит к выводу

DIV event capture
A event capture
A event bubbling
DIV event bubbling

Пример 2: добавление stopPropagation() в функцию

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

результаты на выходе

DIV event capture

Слушатель события предотвратил дальнейшее распространение события вниз и вверх. Однако это не помешало действию по умолчанию (открытие новой вкладки).

Пример 3: добавление stopPropagation() к функции

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
    ev.stopPropagation();
}

или функция

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

результаты на выходе

DIV event capture
A event capture
A event bubbling

Это связано с тем, что оба прослушивателя событий зарегистрированы в одной и той же цели события. Слушатели события предотвратили дальнейшее распространение события вверх. Однако они не помешали действию по умолчанию (открытие новой вкладки).

Пример 4: добавление preventDefault() к любой функции, например

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

предотвращает открытие новой вкладки.

Ответ 3

вернуть ложь;


return false; делает 3 отдельные вещи, когда вы называете это:

  1. event.preventDefault() - останавливает поведение браузера по умолчанию.
  2. event.stopPropagation() - предотвращает распространение (или " event.stopPropagation() события DOM.
  3. Останавливает выполнение обратного вызова и немедленно возвращается при вызове.

Обратите внимание, что это поведение отличается от обычных (не jQuery) обработчиков событий, в которых, в частности, return false не останавливает всплывающее событие.

preventDefault();


preventDefault(); делает одно: останавливает поведение браузера по умолчанию.

Когда их использовать?


Мы знаем, что они делают, но когда их использовать? Просто это зависит от того, чего вы хотите достичь. Используйте preventDefault(); если вы хотите "просто" предотвратить поведение браузера по умолчанию. Используйте return false; когда вы хотите предотвратить поведение браузера по умолчанию и предотвратить распространение DOM события. В большинстве ситуаций, где вы бы использовали return false; то, что вы действительно хотите, это preventDefault().

Примеры:


Давайте попробуем разобраться с примерами:

Мы увидим чистый пример JAVASCRIPT

Пример 1:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Ответ 4

Это цитата из здесь

event.preventDefault

Метод preventDefault не позволяет событию выполнять свои функции по умолчанию. Например, вы должны использовать preventDefault для элемента A, чтобы не нажимать на этот элемент, оставляя текущую страницу:

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

В то время как функциональность элемента по умолчанию блокируется, событие продолжает пузыриться в DOM.

event.stopPropagation

Второй метод stopPropagation позволяет использовать функциональные возможности по умолчанию, но предотвращает распространение события:

//clicking the element will allow the default action to occur but propagation will be stopped...
myChildElement.onclick = function(e) { 
    e.stopPropagation();
    console.log('prop stop! no bubbles!'); 
};

//since propagation was stopped by the child element onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

stopPropagation эффективно останавливает родительские элементы от знания о данном событии на его дочернем элементе.

В то время как простой метод остановки позволяет нам быстро обрабатывать события, это важно подумать о том, что именно вы хотите совершить с пузыриться. Я бы поспорил, что все, что действительно хочет разработчик, - preventDefault 90% времени! Неправильно "прекращение" события может привести к многочисленные проблемы по линии; ваши плагины могут не работать, и ваши сторонние плагины могут быть замаскированы. Или еще хуже - ваш код нарушает другие функции на сайте.

Ответ 5

event.preventDefault(); Остановка действия элемента по умолчанию.

event.stopPropagation(); Предотвращает появление пузырьков в дереве DOM, предотвращая уведомление родительских обработчиков о событии.

Например, если есть ссылка с методом кликов, прикрепленная внутри DIV или FORM, которая также имеет прикрепленный метод щелчка, это предотвратит запуск метода DIV или FORM.

Ответ 6

Событие. preventDefault- останавливает поведение браузера по умолчанию. Теперь перейдем к поведению браузера по умолчанию. Предположим, у вас есть тег привязки, у него есть атрибут href, и этот тег привязки вложен в тег div, который получил событие click. Поведение по умолчанию тега привязки происходит при нажатии на тег привязки, по которому он должен перемещаться, но в случае event.preventDefault он останавливает навигацию. Но это никогда не останавливает пузыри события или эскалации события, т.е.

<div class="container">
 <a href="#" class="element">Click Me!</a>
</div>

$('.container').on('click', function(e) {
 console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  console.log('element was clicked');
});

Результат будет

"элемент был нажат"

"контейнер был нажат"

Теперь event.StopPropation останавливает всплывание события или эскалацию события. Теперь с приведенным выше примером

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  e.stopPropagation(); // Now the event won't bubble up
 console.log('element was clicked');
});

Результат будет

"элемент был нажат"

Для получения дополнительной информации обратитесь к этой ссылке https://codeplanet.io/preventDefault-vs-stoppropagation-vs-stopimmediatepropagation/

Ответ 7

$("#but").click(function(event){
console.log("hello");
  event.preventDefault();
 });


$("#foo").click(function(){
 alert("parent click event fired !");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>