[javascript] What's the difference between event.stopPropagation and event.preventDefault?

They seem to be doing the same thing...
Is one modern and one old? Or are they supported by different browsers?

When I handle events myself (without framework) I just always check for both and execute both if present. (I also return false, but I have the feeling that doesn't work with events attached with node.addEventListener).

So why both? Should I keep checking for both? Or is there actually a difference?

(I know, a lot of questions, but they're all sort of the same =))

This question is related to javascript events preventdefault stoppropagation

The answer is


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


TL;DR
event.preventDefault()
Prevents the browsers default behaviour (such as opening a link), but does not stop the event from bubbling up the DOM.

event.stopPropagation()
Prevents the event from bubbling up the DOM, but does not stop the browsers default behaviour.

return false;
Usually seen in jQuery code, it Prevents the browsers default behaviour, Prevents the event from bubbling up the DOM, and immediately Returns from any callback.

One should checkout this really nice & easy 4 min read with examples from where the above piece was copied from.


Terminology

From quirksmode.org:

Event capturing

When you use event capturing

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

the event handler of element1 fires first, the event handler of element2 fires last.

Event bubbling

When you use event bubbling

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

the event handler of element2 fires first, the event handler of element1 fires last.

Any event taking place in the W3C event model is first captured until it reaches the target element and then bubbles up again.

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

Interface

From w3.org, for event capture:

If the capturing EventListener wishes to prevent further processing of the event from occurring it may call the stopPropagation method of the Event interface. This will prevent further dispatch of the event, although additional EventListeners registered at the same hierarchy level will still receive the event. Once an event's stopPropagation method has been called, further calls to that method have no additional effect. If no additional capturers exist and stopPropagation has not been called, the event triggers the appropriate EventListeners on the target itself.

For event bubbling:

Any event handler may choose to prevent further event propagation by calling the stopPropagation method of the Event interface. If any EventListener calls this method, all additional EventListeners on the current EventTarget will be triggered but bubbling will cease at that level. Only one call to stopPropagation is required to prevent further bubbling.

For event cancelation:

Cancelation is accomplished by calling the Event's preventDefault method. If one or more EventListeners call preventDefault during any phase of event flow the default action will be canceled.

Examples

In the following examples, a click on the hyperlink in the web browser triggers the event's flow (the event listeners are executed) and the event target's default action (a new tab is opened).

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);

Example 1: it results in the output

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

Example 2: adding stopPropagation() to the function

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

results in the output

DIV event capture

The event listener prevented further downward and upward propagation of the event. However it did not prevent the default action (a new tab opening).

Example 3: adding stopPropagation() to the function

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

or the function

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

results in the output

DIV event capture
A event capture
A event bubbling

This is because both event listeners are registered on the same event target. The event listeners prevented further upward propagation of the event. However they did not prevent the default action (a new tab opening).

Example 4: adding preventDefault() to any function, for instance

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

prevents a new tab from opening.


This is the quote from here

Event.preventDefault

The preventDefault method prevents an event from carrying out its default functionality. For example, you would use preventDefault on an A element to stop clicking that element from leaving the current page:

//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!'); 
};

While the element's default functionality is bricked, the event continues to bubble up the DOM.

Event.stopPropagation

The second method, stopPropagation, allows the event's default functionality to happen but prevents the event from propagating:

//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 effectively stops parent elements from knowing about a given event on its child.

While a simple stop method allows us to quickly handle events, it's important to think about what exactly you want to happen with bubbling. I'd bet that all a developer really wants is preventDefault 90% of the time! Incorrectly "stopping" an event could cause you numerous troubles down the line; your plugins may not work and your third party plugins could be bricked. Or worse yet -- your code breaks other functionality on a site.


Event.preventDefault- stops browser default behaviour. Now comes what is browser default behaviour. Assume you have a anchor tag and it has got a href attribute and this anchor tag is nested inside a div tag which has got a click event. Default behaviour of anchor tag is when clicked on the anchor tag it should navigate, but what event.preventDefault does is it stops the navigation in this case. But it never stops the bubbling of event or escalation of event i.e

<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');
});

The result will be

"element was clicked"

"container was clicked"

Now event.StopPropation it stops bubbling of event or escalation of event. Now with above example

$('.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');
});

Result will be

"element was clicked"

For more info refer this link https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/


event.preventDefault(); Stops the default action of an element from happening.

event.stopPropagation(); Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.

For example, if there is a link with a click method attached inside of a DIV or FORM that also has a click method attached, it will prevent the DIV or FORM click method from firing.


return false;


return false; does 3 separate things when you call it:

  1. event.preventDefault() – It stops the browsers default behaviour.
  2. event.stopPropagation() – It prevents the event from propagating (or “bubbling up”) the DOM.
  3. Stops callback execution and returns immediately when called.

Note that this behaviour differs from normal (non-jQuery) event handlers, in which, notably, return false does not stop the event from bubbling up.

preventDefault();


preventDefault(); does one thing: It stops the browsers default behaviour.

When to use them?


We know what they do but when to use them? Simply it depends on what you want to accomplish. Use preventDefault(); if you want to “just” prevent the default browser behaviour. Use return false; when you want to prevent the default browser behaviour and prevent the event from propagating the DOM. In most situations where you would use return false; what you really want is preventDefault().

Examples:


Let’s try to understand with examples:

We will see pure JAVASCRIPT example

Example 1:

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

Run the above code you will see the hyperlink ‘Click here to visit stackoverflow.com‘ now if you click on that link first you will get the javascript alert Link Clicked Next you will get the javascript alert div Clicked and immediately you will be redirected to stackoverflow.com.

Example 2:

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

Run the above code you will see the hyperlink ‘Click here to visit stackoverflow.com‘ now if you click on that link first you will get the javascript alert Link Clicked Next you will get the javascript alert div Clicked Next you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event prevented‘ and you will not be redirected to stackoverflow.com. This is due > to event.preventDefault() method we used to prevent the default click action to be triggered.

Example 3:

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

This time if you click on Link the function executeParent() will not be called and you will not get the javascript alert div Clicked this time. This is due to us having prevented the propagation to the parent div using event.stopPropagation() method. Next you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event is going to be executed‘ and immediately you will be redirected to stackoverflow.com. This is because we haven’t prevented the default click action from triggering this time using event.preventDefault() method.

Example 4:

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

If you click on the Link, the function executeParent() will not be called and you will not get the javascript alert. This is due to us having prevented the propagation to the parent div using event.stopPropagation() method. Next you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event prevented‘ and you will not be redirected to stackoverflow.com. This is because we have prevented the default click action from triggering this time using event.preventDefault() method.

Example 5:

For return false I have three examples and all appear to be doing the exact same thing (just returning false), but in reality the results are quite different. Here's what actually happens in each of the above.

cases:

  1. Returning false from an inline event handler prevents the browser from navigating to the link address, but it doesn't stop the event from propagating through the DOM.
  2. Returning false from a jQuery event handler prevents the browser from navigating to the link address and it stops the event from propagating through the DOM.
  3. Returning false from a regular DOM event handler does absolutely nothing.

Will see all three example.

  1. Inline return false.

_x000D_
_x000D_
<div onclick='executeParent()'>_x000D_
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>_x000D_
</div>_x000D_
<script>_x000D_
  var link = document.querySelector('a');_x000D_
_x000D_
  link.addEventListener('click', function() {_x000D_
    event.currentTarget.innerHTML = 'Click event prevented using inline html'_x000D_
    alert('Link Clicked');_x000D_
  });_x000D_
_x000D_
_x000D_
  function executeParent() {_x000D_
    alert('Div Clicked');_x000D_
  }_x000D_
</script>
_x000D_
_x000D_
_x000D_

  1. Returning false from a jQuery event handler.

_x000D_
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div>_x000D_
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>_x000D_
</div>_x000D_
<script>_x000D_
  $('a').click(function(event) {_x000D_
    alert('Link Clicked');_x000D_
    $('a').text('Click event prevented using return FALSE');_x000D_
    $('a').contents().unwrap();_x000D_
    return false;_x000D_
  });_x000D_
  $('div').click(function(event) {_x000D_
    alert('Div clicked');_x000D_
  });_x000D_
</script>
_x000D_
_x000D_
_x000D_

  1. Returning false from a regular DOM event handler.

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

Hope these examples are clear. Try executing all these examples in a html file to see how they work.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to events

onKeyDown event not working on divs in React Detect click outside Angular component Angular 2 Hover event Global Events in Angular How to fire an event when v-model changes? Passing string parameter in JavaScript function Capture close event on Bootstrap Modal AngularJs event to call after content is loaded Remove All Event Listeners of Specific Type Jquery .on('scroll') not firing the event while scrolling

Examples related to preventdefault

React onClick and preventDefault() link refresh/redirect? Bootstrap 3 - disable navbar collapse How to preventDefault on anchor tags? Stop form from submitting , Using Jquery Prevent Default on Form Submit jQuery What's the difference between event.stopPropagation and event.preventDefault? What is the opposite of evt.preventDefault(); How to unbind a listener that is calling event.preventDefault() (using jQuery)? event.preventDefault() function not working in IE

Examples related to stoppropagation

What's the difference between event.stopPropagation and event.preventDefault?