Check out a free preview of the full Svelte Fundamentals course:
The "Events" Lesson is part of the full, Svelte Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Rich discusses listening to DOM events and demonstrates inline event handlers, event modifiers, component events, event forwarding, and DOM event forwarding. Student questions regarding if forwarding works with callbacks and how to know if an event needs to be forwarded are also covered in this segment.

Get Unlimited Access Now

Transcript from the "Events" Lesson

[00:00:00]
>> We're gonna talk about DOM events as we saw in the earlier exercises where we're clicking a button, you can listen to any DOM event on any element, such as a click or a pointer move or anything else by using this little on directive. So here and inside this application, we have a div, we would like to add an event handler too, do on:pointermove.

[00:00:31] And then we're gonna reference this handle move function up here. Right, and now, if we run the mouse over the iframe, you'll see that the pointer is updating. Actually looks pretty wild. I don't think I realized that pointer move events will give you fractional values, or maybe it's because I've zoomed in this website for the sake of the workshop.

[00:00:58] So I'm just gonna go ahead and make that look a little prettier, get some math around in there, All right? So much nicer. And of course, we don't need to have a named function like handle move, we can just declare the function in line if we want. So we can just copy this whole thing and put it in there if you like.

[00:01:33] And I'm gonna turn it into an anonymous arrow function because syntactically it's a lot simpler. And changes the name of the event E. And rather than assigning to the properties individually, let's just change this to m = x: e.clientX, y: e.clientY, client x and client y are values that you get inside any mouse or pointer event handler, it's the same deal.

[00:02:13] It's giving us these fractional values. Out of that kind of OCD, I'm gonna fix that with some math rounds, right? And now we have an inline event handler that is causing this value here to update. And it's totally fine to use an inline event handler as opposed to a named event handler.

[00:02:37] It's not gonna get, like that function, isn't gonna get recreated every time things change, which is what can happen in some frameworks. The compiler is always got your back it's gonna try and do the right thing. We can modify events using this concise modifier syntax. So here we have a click handler that is gonna cause an alert to appear every time we click it, click that, click it again.

[00:03:06] It's just gonna keep on coming. Maybe we want this event to fire once and then for that event handler to be unregistered. So we can add the once modifier like that. And now if we click it the first time, it'll happen but then after that, nothing happens at all.

[00:03:22] All right, we've got a few different modifiers that we can add. Prevent default, stop propagation, passive, non-passive, capture, once, self, you can read about these in your own time. You don't have exercises for each of these. These are just things that make your life a little bit easier when you're dealing with lots of events.

[00:03:38] And you can use multiple modifiers together by chaining them using this syntax. It's not just elements that fire events, components can also fire events. But the component needs to make itself an event dispatcher. So we've got two components in this exercise an app.svelte and inner.svelte, and the app is gonna listen for events from the inner, side inner.

[00:04:03] We want to create this Event Dispatcher, by importing create Event Dispatcher from svelte. And then we'll create a new dispatch function. Now the reason that we need to do it in two steps like this, first we import create Event Dispatcher, and then we create the dispatcher, is because when we call create Event Dispatcher, svelte knows that we're currently inside the inner component.

[00:04:41] Later when we call dispatch, it knows that it's the dispatcher that belongs to that component. If we just imported a dispatch function, then svelte would have no way of knowing which function was actually dispatching the event. Now that we've done that, so the button if you click it, it will call this say hello function, which calls that dispatch function.

[00:05:08] Now that we've wired that up, we can add an event handler inside app.svelte, and it's exactly the same syntax that we used with DOM elements on message=, then we've got a message handler set up here, handle message. So we'll just feed that in like so. And now if you click the button, it says hello, as you'd expect.

[00:05:34] And there's nothing special about the the name message. We could change that to say, greet, and then in app.svelte, change that also to greet. And a component can have as many different events as makes sense. Now in some frameworks, we don't have event systems, instead you pass callbacks as props into your components.

[00:06:04] And that's the thing that you can do in svelte too, it's really kind of a personal style preference the basic advice is that your data goes down and then events come up and whether those events are expressed using event dispatchers in Svelte or whether expressed as callbacks that the component then calls is really just a matter of code style.

[00:06:24] I personally like the event style but it's up to you you're not forced to choose between one or the other. Okay, so a fact about DOM events that you'll know if you've used the DOM a lot is that events bubble, which is to say that if you have some element deep in your tree, you can add an event listener on any parent and the event will bubble up from the event target to where your event handler is registered.

[00:06:52] That is not true with components, component events do not bubble. So if you want to listen to an event on some deeply nested component, the intermediate components need to forward the event upwards. And so in this case we have the same app.svelte and inner.svelte as in the exercise that we just did, but there's also now this outer svelte which contains the inner svelte component.

[00:07:16] So this is the middleman that's gonna need to forward the event from outer. Now, we could solve this by going through the whole rigmarole of importing, create Event Dispatcher, and then creating a dispatch function, and then adding an event listener to the inner here, it's a lot of work.

[00:07:38] It's a lot of boilerplate and boilerplate is anathema to the svelte way of doing things. So we have a convenient shorthand, instead, when this event gets dispatched, we can just forward it to the application by adding on :message. And now the outer component will dispatch that message when it receives it from the inner component.

[00:08:14] And of course, it works exactly the same way for DOM events. We have a big red button component here. And we have a button, we wanna get notifications of when the user clicks on that button. We've got our onClick handler wired up already inside app.svelte, I'm gonna call this handleClick function, so we just need to add an onClick to that.

[00:08:41] And now when press the button, [SOUND].
>> Does forwarding only work with events or callbacks as well.
>> No, it does not work in callbacks, it is purely about events. So if you're using the callback style, then you will have to pass the callback from the parent component through the intermediate component to the child component in the same way that you currently need to add the forwarding syntax for the events.

[00:09:10] Okay, so we got a question in the chat just now that was basically, how do I know in outet.svelte that I need to forward this message event? Where is that event coming from? And the answer is it's coming from us, we added it ourselves. In inner.svelte, when we call dispatch, the name of the event that we pass into the dispatch function that is the name of the event that gets emitted from the component.

[00:09:36] And so anything that includes inner.svelte can listen for those events or forward them rather by adding that. And that will now cause the outer component to emit a message event that the app can listen to with its own on message handler.
>> So like a pop sound?

[00:09:59]
>> Yeah, you can think of it that way, yeah.