Handling Component and DOM Events in Svelte Apps
Tags: svelte, webdev, programming, javascript
Published: 2021-01-28 21:38:42

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


Svelte is an up and coming front end framework for developing front end web apps.

It’s simple to use and lets us create results fast.

In this article, we’ll look at how to handle DOM events in Svelte components.

### Events

We can use the `on:` directive to handle events. For instance, we can write the following to get the mouse position as we move our mouse around the screen:

`App.svelte` :

```
<script>
  let pos = { x: 0, y: 0 };

  const handleMousemove = event => {
    pos.x = event.clientX;
    pos.y = event.clientY;
  };
</script>

<style>
  div {
    width: 100vw;
    height: 100vh;
  }
</style>

<div on:mousemove={handleMousemove}>
  The mouse position is {pos.x} x {pos.y}
</div>
```

In the code above, we have `on:mousemove={handleMousemove}` to attach the `handleMousemove` handler to our div.

The `handleMousemove` function has the `event` parameter, which is the `MouseEvent` object.

Therefore, we can access the mouse position with the `clientX` and `clientY` properties for the x and y position of the mouse respectively.

In the end, we display them on the screen.

Event handlers can also be declared inline as follows:

`App.svelte` :

```
<script>
  let pos = { x: 0, y: 0 };
</script>

<style>
  div {
    width: 100vw;
    height: 100vh;
  }
</style>

<div on:mousemove={event => {
    pos.x = event.clientX;
    pos.y = event.clientY;
  }}>
  The mouse position is {pos.x} x {pos.y}
</div>
```

Or we can put them between quotes as follows:

`App.svelte` :

```
<script>
  let pos = { x: 0, y: 0 };
</script>

<style>
  div {
    width: 100vw;
    height: 100vh;
  }
</style>

<div on:mousemove="{event => {
    pos.x = event.clientX;
    pos.y = event.clientY;
  }}">
  The mouse position is {pos.x} x {pos.y}
</div>
```

The quotes provide syntax highlighting in some environments, but they’re optional.

Inline event handler doesn’t impact the performance of the app since Svelte will optimize it by not attaching and detaching on the fly.

### Modifiers

DOM event directives can have modifiers attached to them to change their behavior.

For instance, we can add the `once` modifier to the `on:click` directive to only listen to mouse click of an element once:

`App.svelte` :

```
<script>
  const handleClick = () => {
    alert("alert");
  };
</script>

<button on:click|once={handleClick}>
  Click Me Once
</button>
```

The `once` modifier in the code above only runs the `handleClick` handler once, so if we click the button again, it’ll run nothing.

Other modifiers include:

*   `preventDefault` — calls `event.preventDefault` before running the handler
*   `stopPropagation` — calls `event.stopPropagation` to prevent the event from reaching the next element
*   `passive` — improves scrolling performance on touch or wheel events
*   `capture` — fires handlers during the capture phase instead of the bubbling phase
*   `self` — only trigger handler if `event.target` is the element itself.

They can also be chained together like `on:click|once|self` .

![](https://cdn-images-1.medium.com/max/800/0*4tRmUWyXorzS61bm)Photo by [Marvin Meyer](https://unsplash.com/@marvelous?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

### Component Events

Components can also dispatch events. For instance, we can write the following code to dispatch an event from a child to a parent:

`App.svelte` :

```
<script>
  import Button from "./Button.svelte";
  const handleGreet = event => {
    alert(event.detail.text);
  };
</script>

<Button on:greet={handleGreet} />
```

`Button.svelte` :

```
<script>
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();

  const greet = () => {
    dispatch("greet", {
      text: "Hello Mary"
    });
  };
</script>

<button on:click={greet}>
  Send Greeting
</button>
```

In `Button`, we create the `dispatch` constant with the `createEventDispatcher` function. `dispatch` is a function, which we call with the event name and the payload to send with the event emission as the arguments.

Then in `App` , we listen to the `greet` event emitted from `Button` by attaching the `handleGreet` event listener to the `on:greet` directive.

When `handleGreet` runs after the `greet` event is emitted, then the `event` object has the data sent with the event emission and we retrieved it with `event.detail.text` .

Therefore, when we click the Send Greeting button, we see ‘Hello Mary’ displayed in an alert box.

### Event Forwarding

Component events don’t bubble like DOM events. To forward them to another component, we can add a `forward` function, which calls `dispatch` .

Then we can listen to the event in the component where the event is forwarded to.

For instance, we can write:

`Button.svelte` :

```
<script>
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();

  const greet = () => {
    dispatch("greet", {
      text: "Hello Mary"
    });
  };
</script>

<button on:click={greet}>
  Send Greeting
</button>
```

`Parent.svelte` :

```
<script>
  import Button from "./Button.svelte";
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();

  const forward = () => {
    dispatch("greet", event.detail);
  };
</script>

<Button on:greet />
```

`App.svelte` :

```
<script>
  import Parent from "./Parent.svelte";
  const handleGreet = event => {
    alert(event.detail.text);
  };
</script>

<Parent on:greet={handleGreet} />
```

In the code above, `Button.svelte` emits the `greet` event, then the `Parent.svelte` component forwards the event, then `App.svelte` listens to the `greet` event.

In `Parent.svelte` ,

```
<Button on:greet />
```

is the same as:

```
<Button on:greet={forward} />
```

### DOM Event Forwarding

We can forward DOM events like component events. For instance, we can write:

`Button.svelte` :

```
<button on:click>
  Send Greeting
</button>
```

`Parent.svelte` :

```
<script>
  import Button from "./Button.svelte";
</script>

<Button on:click />
```

`App.svelte` :

```
<script>
  import Parent from "./Parent.svelte";
  const handleClick = event => {
    alert("Hello");
  };
</script>

<Parent on:click={handleClick} />
```

The code above forwards the click event from `Button`to `Parent` and `Parent` to `App` .

Therefore, we’ll see a ‘Hello’ alert displayed on the screen when we click the Send Greeting button.

### Conclusion

Svelte components and DOM elements can have event handlers attached to them.

We listen to events using the `on:` directives with modifiers.

Events can be forwarded with the `on:` directive without any value set to it.