7 Event Modifiers in Svelte You Must Know
Tags: svelte, eventmodifiers, sveltetips, beginners
Published: 2021-04-07 03:09:42

---
title: 7 Event Modifiers in Svelte You Must Know
published: true
description: Why do we need event modifiers at all? What you'll learn will changed your mind
tags: svelte,eventmodifiers,sveltetips,beginners
series: "Svelte for Beginners"
//cover_image: https://direct_url_to_image.jpg
---

This is how you add event listener in Svelte

```html
<script>
  function onClick(event) {
  }
</script>

<button on:click={onClick} />
```

Under the hood, it is calling [`addEventListener()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) from the DOM API.

The `addEventListener()` takes in 2 parameters, the event type and the listener; and optionally takes in a 3rd parameter, which is the `option` object.

The `option` is where you can specify whether to set up the event listener in `capture` phase, or making it `passive`. But how do you pass in this option in Svelte?

...

## Introducing the Event Modifiers!

Event Modifiers help pass in options to your `addEventListener`, as well as simplify common patterns in event listener.

Here are the 7 event modifiers you must know!

## 1. preventDefault

How often you need to call `event.preventDefault()` to prevent default behavior from the browser? prevent form from submitting, prevent browser disallow drag-and-drop, ...

The `preventDefault` modifier helps you do that easily.

```html
<script>
  function onClick(event) {}
</script>

<button on:click|preventDefault={onClick} />
```

This is equivalent of calling event.preventDefault() on the start of the event handler

```html
<script>
  function onClick(event) {}

  function onClickEquivalent(event) {
    event.preventDefault();
    onClick(event);
  }
</script>

<button on:click={onClickEquivalent} />
```

## 2. stopPropagation

Have you used `event.stopPropagation` to prevent event from bubbling up to its parents?

You can easily do that with the `stopPropagation` modifier!

```html
<script>
  function onClick(event) {}
</script>

<button on:click|stopPropagation={onClick} />
```

This is equivalent of calling `event.stopPropagation()` on the start of the event handler

```html
<script>
  function onClick(event) {}

  function onClickEquivalent(event) {
    event.stopPropagation();
    onClick(event);
  }
</script>

<button on:click={onClickEquivalent} />
```

## 3. passive

For performance reasons, you may want to specify `{ passive: true }` to indicate to the browser that you will not call `event.preventDefault()`. This is often used to [improve the scrolling performance for scroll event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners)

You can do this with the `passive` modifier

```html
<script>
  function onScroll(event) {}
</script>

<div on:scroll|passive={onScroll} />
```

This is equivalent of calling `addEventListener()` with `{ passive: true }`

```html
<script>
  function onScroll(event) {}

  let element;
  onMount(() => {
    element.addEventListener('scroll', onScroll, { passive: true });

    return () => {
      element.removeEventListener('scroll', onScroll, { passive: true });
    }
  });
</script>

<div bind:this={element} />
```

## 4. nonpassive

`passive: true` is great, and [Chrome is making them `passive` by default](https://developers.google.com/web/updates/2017/01/scrolling-intervention) if you do not pass in the option for `passive`.

If you want to opt this out, you'll have to specify `{ passive: false }`

which leads to the `nonpassive` event modifier

```html
<script>
  function onScroll(event) {}
</script>

<div on:scroll|nonpassive={onScroll} />
```

This is equivalent of calling `addEventListener()` with `{ passive: false }`

```html
<script>
  function onScroll(event) {}

  let element;
  onMount(() => {
    element.addEventListener('scroll', onScroll, { passive: false });

    return () => {
      element.removeEventListener('scroll', onScroll, { passive: false });
    }
  });
</script>

<div bind:this={element} />
```

## 5. once

Sometimes you want the event listener to be called only once. You want to remove the event listener as soon as it's being called.

The `once` modifier helps you do that

```html
<script>
  function onClick(event) {}
</script>

<button on:click|once={onClick} />
```

This is equivalent of calling `addEventListener()` with `{ once: true }`

```html
<script>
  function onClick(event) {}

  let element;
  onMount(() => {
    element.addEventListener('click', onClick, { once: true });

    return () => {
      element.removeEventListener('click', onClick, { once: true });
    }
  });
</script>

<button bind:this={element} />
```

## 6. capture

Sometimes, you want to register the event listener for the [capturing phase](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling_and_capture).

You can do it with the `capture` event modifier

```html
<script>
  function onClick(event) {}
</script>

<button on:click|capture={onClick} />
```

This is equivalent of calling `addEventListener()` with `{ capture: true }`

```html
<script>
  function onClick(event) {}

  let element;
  onMount(() => {
    element.addEventListener('click', onClick, { capture: true });

    return () => {
      element.removeEventListener('click', onClick, { capture: true });
    }
  });
</script>

<button bind:this={element} />
```


## 7. self

Lastly, you want the event listener to be called only when the event is dispatched from the element itself, and NOT from its children.

You do that with the `self` event modifier

```html
<script>
  function onClick(event) {}
</script>

<button on:click|self={onClick} />
```

This is equivalent of checking if the `event.target` === current element

```html
<script>
  function onClick(event) {}
  
  let element;
  function onClickEquivalent(event) {
    if (event.target === element) {
      onClick(event);
    }
  }
</script>

<button bind:this={element} on:click={onClickEquivalent} />
```

## Event modifiers can be chained

There are times where you want to apply more than 1 event modifiers, and YES you can do that.

```html
<button on:click|self|stopPropagation|preventDefault={onClick} />
```

You can chain as many event modifiers as you like, and the order does not matter.

However, by the nature of `passive` and `preventDefault`, you can't use them together

```html
<button on:click|passive|preventDefault={onClick} />
<!-- Error: The 'passive' and 'preventDefault' modifiers cannot be used together -->
```

Do you learn better with video? I've made a video explaining how to add event listeners and cover each of the event modifiers in depth with examples

{% youtube pbGe5F0Kyi8 %}