Skip to content

docs: event delegation tweaks #12597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions documentation/docs/02-template-syntax/02-basic-markup.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,16 @@ Because events are just attributes, the same rules as for attributes apply:
- you can spread them: `<button {...thisSpreadContainsEventAttributes}>click me</button>`
- component events are just (callback) properties and don't need a separate concept

Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, events are either listened to directly through `addEventListener`, or the event is delegated.

### Event delegation

To reduce the memory footprint and increase performance, Svelte uses a technique called event delegation. This means that certain events are only listened to once at the application root, invoking a handler that then traverses the event call path and invokes listeners along the way.

There are a few gotchas you need to be aware of when it comes to event delegation:

- when you dispatch events manually, make sure to set the `{ bubbles: true }` option
- when listening to events programmatically (i.e. not through `<button onclick={...}>` but through `node.addEventListener`), be careful to not call `stopPropagation` or else the delegated event handler won't be reached and handlers won't be invoked. For this reaon it's best to use `on` (which properly handles `stopPropagation`) from `svelte/events` instead of `addEventListener` to make sure the chain of events is preserved
- when you manually dispatch an event with the same name as one of the delegated ones, make sure to set the `{ bubbles: true }` option
- when listening to events programmatically (i.e. not through `<button onclick={...}>` but through `node.addEventListener`), be careful to not call `stopPropagation` or else the delegated event handler won't be reached and handlers won't be invoked. Similarly, event listeners added manually and higher up the DOM tree will be invoked _before_ events that are delegated and deeper down the DOM tree (because the actual event reaction happens in the delegated handler at the root). For these reasons it's best to use `on` (which properly handles `stopPropagation`) from `svelte/events` instead of `addEventListener` to make sure the chain of events is preserved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this change is correct? event listeners added above the application root will only be invoked before delegated event handlers if they're capturing. opening a new PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it kind of makes sense. You can have an event listener manually added above an element and that will indeed fire before the root event listener. Now you mention it though, we could definitely explain this differently to be clearer.

Copy link
Member Author

@dummdidumm dummdidumm Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it does fire before them; "higher up the dom tree" does mean "but below the application root"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah wait, higher up but below the root. that needs clarification


The following events are delegated:

Expand Down
Loading