Skip to content

stopPropagation() and preventDefault() in JavaScript

preventdefault-vs-stopbubbling

In this article, we’ll see what is stopPropagation and preventDefault in JavaScript.

In the previous blog post, we looked at what event bubbling is and how we can implement it. If you are unaware of what event bubbling is please take a look at my blog post.

To understand stopPropagation and preventDefault in JavaScript, you need a basic understanding of event bubbling.

What is stopPropagation()?

If you call the stopPropagation() on the event then the event won’t be bubbled up and the parent element will not receive the event triggers.

We’ll use the event bubbling demo code here to stop propagating.

Let me bring the HTML we used in event bubbling blog post.

<table id="grid">
    <thead></thead>
    <tbody>
        <tr>
            <td>row 1 cell 1</td>
            <td>row 1 cell 2</td>
        </tr>
        <tr>
            <td>row 2 cell 1</td>
            <td>row 2 cell 2</td>
        </tr>
        <tr>
            <td>row 3 cell 1</td>
            <td>row 3 cell 2</td>
        </tr>
        <!-- some other tr rows -->
    </tbody>
</table>

When we click event happens on any of the TD element all the parent’s click events also fire up due to event bubbling. Let’s stop the event bubbling when we click on any TD element.

Let’s change the TD click event to have our stopPropagation.

$("td").on("click", function (e) {
  e.stopPropagation();
  alert("td click fired");
});

Once we did the above change, our events won’t be bubbled up top when the click event happens on the TD element.

Stopping the propagation/bubbling can be useful if we use event delegation to have a single event for all the nested elements (ex: a single event on a table element, which will take care of where it was clicked and what action it has to take).

Here is the jsFiddle demo with the propagation stopped on the td element.

Try clicking on any of the TD cells and you should only get one alert instead of getting multiple alerts.

And also click between the TD cells you should see that table, document click event fires. (without stopPropagation)

What is preventDefault()

Unlike stopPropagation(), preventDefault() will prevent the default browser action on that event.

Let’s say we have an input field which is a postal code or PIN code. We don’t want the user to enter alphabets and special characters into the field. The field should only accept numbers.

One way to do this is instead of having the input type as the text we can have the type as a number so that only numbers will be accepted but this will allow the user to decrement or increment the numbers in the input by using arrow keys (up/down).

For this preventDefault, let’s have a text field, and let’s prevent alphabets from entering into the textbox.

So, let‘s wire up a keypress event on our input and call the preventDefault() on the event if the entered character is not a number.

Here is how it can be done.

$("#alpha").keypress(function(event) {
  if (event.which != 8 && isNaN(String.fromCharCode(event.which))) {
    event.preventDefault(); //prevents from being entered
  }
});

Here is the demo.

You can place a console log within the if statement to see the prevented keystroke. As you type alphabets, they will not be shown in the textbox.

Only numbers are allowed in the textbox as we are preventing the default action (inserting character as it is typed) from happening with the preventDefault function.

So, if you have any keypress events registered on the parent element or ancestors, those will still be fired due to the bubbling effect. e.preventDefault() will not stop the bubbling.

Returning false from the event handler in jQuery

Returning false from an event in jQuery will have two effects.

The return false; statement in a jQuery event listener does both the stopPropagation and preventDefault.

Let’s add a body keypress listener along with the keypress event on the input field.

$("body").keypress(function() {
  alert("body key press");
})
$("#alpha").keypress(function(event) {
  if (event.which != 8 && isNaN(String.fromCharCode(event.which))) {
    event.preventDefault();
  }
});

So, whenever we press a key in the text box, if the key is other than a number then the character won’t be inserted into the text box and we will show an alert to the user as we have a key press event registered on the body tag.

The alert will still be triggered though we enter a number as we are not stopping the propagation in the input field.

Now, let’s replace the event.preventDefault() statement with a return false and try that in the fiddler.

Here is the modified jsFiddle.

You can observe that the alert in the body event will no longer be shown when we press any alphabet. This is because we are stopping the bubbling and preventing (stopPropagation() and preventDefault()) the default action on the event with a return false statement.

Best place to handle actions in the event

We can stop the event actions anywhere in the event handler.

I’d recommend adding these event actions at the beginning of the event handler function.

If you have the event action (say e.stopPropagation()) at the end of the function, and if your functional code has any run-time errors, then our e.stopPropagation() statement will not be reached and because of to the event bubbling effect, we might end up triggering the events up the hierarchy.

Example:

  $("td").on("click", function (e) {
    //functional code here
    e.stopPropagation();
  });

As you can see from the above code if the function piece of code has any errors the rest of the lines won’t be executed and our e.stopPropagation() statement will not be considered.

Instead of having the e.stopPropagation() at the end of the handler, if we can have it at the beginning of the handler then though our functional code fails, the propagation will not happen (meaning e.stopPropagation() works).

Example:

  $("td").on("click", function (e) {
    e.stopPropagation();
    //functional code here
  });

Conclusion

Both stopPropagation and preventDefault functions are useful for stopping propagation and preventing the default action of the event from happening.

We also should care about the difference between them and when to use one over the other.

Leave a Reply

Your email address will not be published.