В чем разница между событиями.это происходит и событие.метод preventDefault?

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

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

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

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

7 ответов


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

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

давайте вы
<div id="foo">
 <button id="but" />
</div>

$("#foo").click(function() {
   // mouse click on div
});

$("#but").click(function(ev) {
   // mouse click on button
   ev.stopPropagation();
});

пример

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

$("#but").click(function(event){
  event.stopPropagation();
 });


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

С stopPropagation только кнопки нажмите кнопку обработчик и divs click handler никогда пожары.

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

Ниже приведены некоторые документы по объектам событий DOM из MDN и MSDN

MDN:

для IE9 и FF вы можете просто использовать preventDefault & stopPropagation.

для поддержки IE8 и ниже заменить stopPropagation С cancelBubble и заменить preventDefault С returnValue


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

от quirksmode.org:

захват событие

при использовании захвата событий

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

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

пузырящееся событие

при использовании события bubbling

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

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

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

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

интерфейс

С w3.org на захват событие:

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

на пузырящееся событие:

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

на событие отмены:

отмена осуществляется путем вызова the Event ' s 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();
}

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


вернуть false;


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

  1. event.preventDefault() - он останавливает поведение браузеров по умолчанию.
  2. 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>

выполнить приведенный выше код, вы увидите гиперссылка ‘Нажмите здесь, чтобы посетить stackoverflow.com' теперь, если вы нажмете на эту ссылку, вы получите предупреждение javascript Ссылка Далее вы получите javascript тревога!--15-->div нажал и сразу же вы будете перенаправлены на stackoverflow.com.

Пример 2:

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

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

выполнить приведенный выше код, вы увидите гиперссылку, Нажмите здесь посещать stackoverflow.com " теперь, если вы нажмете на эту ссылку, вы получите предупреждение javascript Ссылка Далее вы получите javascript тревога!--15-->div нажал Далее вы увидите гиперссылку, Нажмите здесь визит stackoverflow.com 'заменено текстом' click event prevented‘ а вы не перенаправить на stackoverflow.com - ... Это связано > с событием.метод preventDefault (), который мы использовали для предотвращения щелчка по умолчанию действие вызванный.

Пример 3:

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

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

на этот раз, если вы нажмете на ссылку, функция executeParent() не будет вызывается, и вы не получите предупреждение javascript div нажал эта пора. Это связано с тем, что мы предотвратили распространение Родительский div с помощью события.метод stopPropagation (). Далее вы увидите гиперссылка "Нажмите здесь, чтобы посетить stackoverflow.com' replaced по тексту "Событие Click будет выполнено‘, и вы сразу же будете перенаправлено на stackoverflow.com - ... Это потому, что мы не предотвратили действие щелчка по умолчанию от запуска на этот раз с помощью событие.метод preventDefault ().

Пример 4:

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

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

если вы нажмете на ссылку, функция executeParent() не будет вызывается, и вы не получите предупреждение javascript. Это из-за нас предотвратив распространение на родительский div с помощью событие.метод stopPropagation (). Далее вы увидите гиперссылку " Click здесь, чтобы посетить stackoverflow.com 'заменено текстом' Click event предотвращено", и вы не будете перенаправлены на stackoverflow.com - ... Это это потому, что мы предотвратили запуск действия click по умолчанию на этот раз с помощью event.метод preventDefault ().

Пример 5:

для return false у меня есть три примера, и все они, похоже, делают то же самое (просто возвращают false), но на самом деле результаты совсем другие. Вот что на самом деле происходит в каждом из вышеупомянутое.

случаях:

  1. возвращение false из встроенного обработчика событий предотвращает переход браузера к адресу ссылки, но это не останавливает распространение события через ДОМ.
  2. возвращение false из обработчика событий jQuery предотвращает переход браузера к адресу ссылки и останавливает распространение события через DOM.
  3. возвращение false от обычного обработчика событий DOM абсолютно ничего не делает.

увидим все три примера.

  1. встроенный обратный ложный.

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>
</div>
<script>
  var link = document.querySelector('a');

  link.addEventListener('click', function() {
    event.currentTarget.innerHTML = 'Click event prevented using inline html'
    alert('Link Clicked');
  });


  function executeParent() {
    alert('Div Clicked');
  }
</script>
  1. возвращение false из обработчика событий jQuery.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>
</div>
<script>
  $('a').click(function(event) {
    alert('Link Clicked');
    $('a').text('Click event prevented using return FALSE');
    $('a').contents().unwrap();
    return false;
  });
  $('div').click(function(event) {
    alert('Div clicked');
  });
</script>
  1. возврат false из обычного обработчика событий DOM.

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

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

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


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

событие.метод 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!'); 
};

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

событие.это происходит

второй метод, 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's onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

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

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


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

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

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


событие.preventDefault-останавливает поведение браузера по умолчанию. Теперь приходит то, что поведение браузера по умолчанию. Предположим, у вас есть тег привязки, и у него есть атрибут href, и этот тег привязки вложен в тег div, у которого есть событие click. Поведение по умолчанию якорного тега при нажатии на якорный тег он должен перемещаться, но какое событие.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');
});

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

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

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

сейчас события.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/


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