Comprehensive guide of Event Handling in Svelte

Events are objects that serve as communication units between an emitter and the listeners. In short, any activity that happens on the HTML web page is an event. And with the help of JavaScript (Svelte in this case), we can handle these events.

Comprehensive guide of Event Handling in Svelte

Using the on: directive, Svelte listens for any event on an element. Customised events convey data between child and parent components. Components in Svelte can listen for DOM and custom events. The on:event-name directive specifies how an event will be handled. It's worth noting that the term on comes after a comma and the name of the event. Its value is the function that will be called after the event has been dispatched. The name of the event could be either DOM or custom. The specified function receives an event object.

In this article, we learn about the event handling. Let's proceed.

Events are objects that serve as communication units between an emitter and the listeners. In short, any activity that happens on the HTML web page is an event. And with the help of JavaScript (Svelte in this case), we can handle these events. For Ex- Clicking a button, Submitting a form is one of the few examples of Events

Example of simple Event:

<script>
    
    function eventClickMe() {
    	// Handle something
	}
</script>

<button on:click={eventClickMe}>Click Me</button>

And in the App.svelte

<script>
    import EventComponent from './EventComponent.svelte';
</script>

<main>
    <p> Event communication. </p>
    <hr/>

    <EventComponent />

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}

	h1 {
		color: #ff3e00;
		text-transform: uppercase;
		font-size: 4em;
		font-weight: 100;
	}

	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>

When you load the application, it will look like the below screenshot

You can see a button, but it will not do anything.

Let's add an alert only to check if our events are working correctly.

<script>

    function eventClickMe() {
        alert('I am clicked')
    }
</script>

<button on:click={eventClickMe}>Click Me</button>

How about this 'Inline Event Handler'.

<button on:click={ e => { alert('I am clicked') } }>
    Click Me
</button>

Here is an alternate way of defining the Inline Event Handler using the anonymous function on:click={ e => { alert('I am clicked') } }

Event Dispatcher

Event Dispatching allows developers to add logic to the Svelte application. Using an event dispatcher, we can dispatch events and communicate within the components. Components can forward events by creating and using an event dispatcher.

In the EventComponent.svelte

<script>

    import { createEventDispatcher } from 'svelte'

    const dispatch = createEventDispatcher()

    function eventClickMe() {
        dispatch('message', {
            text: 'Pass to main component'
        });
    }
</script>

<button on:click={eventClickMe}>
    Click Me
</button>

The data given as the second argument to the dispatch function is the detail property of this object. Additional parameters supplied to dispatch are not taken into consideration.

And in the App.svelte

<script>
    import EventComponent from './EventComponent.svelte';

    function handleMessage(event) {
        alert(event.detail.text)
    }

</script>

<main>
    <p> Event communication. </p>
    <hr/>

    <EventComponent on:message={handleMessage}/>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>

Only the parent component receives these events. They don't float to the top of the component hierarchy by themselves. The on:directive is used by parent components to listen for events from child components.

Event Modifiers

We can modify the events in svelte using these modifiers. Following are the modifier that we can use

  • once: remove the handler after the first time it runs.

In the EventComponent.svelte, modify the button with the below code.

<button on:click|once={eventClickMe}>
    Click Me
</button>

You'll notice that, when you try to click the button second time, it'll not show any alert.

  • preventDefault: calls e.preventDefault() before running the handler.

When used with forms, it'll prevent the default submitting of form.

  • stopPropagation: calls e.stopPropagation(). Prevents the propagation of the events within the same handler.
  • passive: improves scrolling performance.
  • capture: fires the handler during the capture phase not on the bubbling phase.
  • self: only trigger handler if event.target is the element itself.

Event Forwarding

We already discussed, When we fire the event only the parent component receives it. It'll not go to hierarchy itself. However, sometimes, we need the events to be used by other parent components. We need to nest the events further up in hierarchy.

Create a new file  FirstEventComponent.svelte, modify the button with the below code.

<script>

    import { createEventDispatcher } from 'svelte'

    const dispatch = createEventDispatcher()

    function eventClickMe() {
        dispatch('message', {
            text: 'Pass to main component'
        });
    }
</script>

<button on:click|preventDefault={eventClickMe}>
    Click Me
</button>

Create a another file  SecondEventComponent.svelte, modify the button with the below code.

<script>
  import FirstEventComponent from './FirstEventComponent.svlete';
  import { createEventDispatcher } from 'svelte';
  
  const dispatch = createEventDispatcher();
  
  function forward(event) {
    dispatch('message', event.detail);
  }
</script>

<FirstEventComponent on:message={forward} />

And in the App.svelte

<script>
    import SecondEventComponent from './SecondEventComponent.svelte';

    function handleMessage(event) {
        alert(event.detail.text)
    }

</script>

<main>
    <p> Event communication. </p>
    <hr/>

    <SecondEventComponent on:message={handleMessage}/>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>

Thats all about the events. Hope you like it. See you in the next article.