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
: callse.preventDefault()
before running the handler.
When used with forms, it'll prevent the default submitting of form.
stopPropagation
: callse.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.