preventDefault vs stopPropagation
Tags: javascript, tutorial, beginners
Published: 2022-02-09 20:07:55

Are you still wondering the difference between `preventDefault` and `stopPropagation`? So you are using both, so at least one will do what you want. At the end of this article you will know what is the role of each one :)

> **Note:** If you do not know these functions, they apply on **Event**s.

## `preventDefault`

Your browser has default actions for some elements that we will see soon. The **`preventDefault`** function will prevent these actions.

> **Note:** Not all **Event*s can be cancelled. If it can't, it will just do nothing.

Let's now see some concrete default actions:

### Hyperlink with `a` HTML element.

When you define an attribute `href` on `a` element, the user will be redirected to the defined url.
This action can be cancelled, so the user will not be redirected to the `href` value.

> **Fun fact:** This is what `react-router` does with their `Link` component. I talk about this in this article: [`react-router` demystified](https://dev.to/romaintrotard/react-router-v6-demystified-part-2-19a9).

![No redirect of link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb86be39v5ejbydm4d15.gif)
 

### Form submission

By default a form will submit the values of input into an `action` endpoint (by default the current location) with the `method` type (by default get).
You can prevent this action with `preventDefault`.

> **Fun fact:** That's what does form libraries in **React** like: `react-hook-form`, `formik`, ... with the `handleSubmit` method.

![Form action prevented](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wasvc1b20g4i0n24rtbr.gif)
 

### Checkbox / radio elements

On `checkbox` and `radio` input, you can `preventDefault` the action on the `click` event.

> **Note:** It's also possible to prevent the action on input text (and other type), on the event `keypress` (will not work on mobiles). 

![Checkbox action prevented](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iezxw0bcfdifn1vn6gag.gif)
 


### Many more

Above, I just listed some of the prevent-able event but there are another ones.

If you want to check if the event you deal with is "prevent-able" you can check the property `cancelable`:

```javascript
console.log('Is prevent-able?', event.cancelable);
```

----

## `stopPropagation`

Now let's talk about `stopPropagation` function. You will have to know some basics about the propagation of events in the **DOM**.

### Prerequisite

One thing to know is the **event propagation process**. There are 3 phases:
- **Capturing phase**: going from the window to the target element.
- **Target phase**: the event has reached the target.
- **Bubbling phase**: going from the target element to the window.

> **Note:** You can see the event phase from the **event** thanks to the **eventPhase** property.

For example when we have the following html:

```html
<html>
  <body>
    <div id="container">
      <button id="myButton">Click me</button>
    </div>
  </body>
</html>
```

And we are clicking on the `button` we have the following event propagation:

![Event propagation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvkw4at0neqtqqtx9ipu.png)
 

> **Note:** `window` is not a DOM element.

### `stopPropagation` role

**_So what does `stopPropagation`?_**

You may have guessed it, when you call the function **`stopPropagation`** on the event, it will stop the propation we have seen previously.

For example, if I stop the propagation on the `div` element during the capturing phase, it will never reach the `button` element.

![Event propagation when stopPropgation executes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30rmfvjco89hhf7wu7fx.png)
 

> **Warning:** If there are other listener on the `div` they will be executed. Here it comes the **`stopImmediatePropagation`** function, not to executes them too.

----

## Bonus: `stopImmediatePropagation`

I have spoiled a little at the end of the previous part. But imagine we have two event listeners on the `button`:
- `eventListener1` FIRST registered handler
- `eventListener2` SECOND registered handler

If we stop the propagation in `eventListener1` (thanks to `stopPropagation`), then both handlers will be executed.

It can happen you do not want to execute other listeners which are on the same element. In this case you will use the **`stopImmediatePropagation`** method on the `event`.

```javascript
const button = document.getElementById("myButton");

button.addEventListener("click", (event) => {
  event.stopImmediatePropagation();
  console.log("This handler is executed");
});

button.addEventListener("click", (event) => {
  console.log("This handler will never be executed");
});
```

----

## Conclusion

We made it. As you can see it's not a complex concept but so important to know.
To summarize:
- **`preventDefault`** will prevent the default action of the browser to be executed. For example: form submission, navigation when clicking on `a` with href, ...
- **`stopPropagation`** will stop the propagation of the event. (see the prerequisite image on `stopPropagation` part)
- **`stopImmediatePropagation`** will stop the propagation of event AND will not execute other listener on the same element.

----

Do not hesitate to comment and if you want to see more, you can follow me on [Twitter](https://twitter.com/romain_trotard ) or go to my [Website](https://www.romaintrotard.com).