If you are an avid user of Svelte, you would know by now that we can create custom events in Svelte using the createEventDispatcher
method.
However, there is one problem - the current version of Svelte does not bubble the custom events out of the box. As suggested by one of the maintainers of Svelte here, bubbling of custom events in Svelte would probably only be supported in v4 of Svelte. Having said that, event delegation for custom events will not work.
For example, let's say we have a child component, Nested.svelte
that dispatches the custom event, my-event
and let's say we have a parent component, App.svelte
that contains a delegated event listener, listening for the my-event
event:
Nested.svelte
<script>
import {createEventDispatcher} from 'svelte';
const dispatch = createEventDispatcher();
const handleClick = ()=>{
dispatch("my-event", "nested component is clicked")
}
</script>
<div class="nested" on:click={handleClick}>
nested component
</div>
<style>
.nested{
color:white;
background-color:blue;
}
</style>
The following delegated event listener in the App.svelte
component would not receive the my-event
event because custom events dispatched using Svelte's createEventDispatcher
will not bubble.
App.svelte
<script>
import Nested from "./Nested.svelte";
document.addEventListener("my-event", (e)=>{
console.log(e.detail)
})
</script>
<div class="parent">
Parent component
<!--on:my-event is required here so that the event is forwarded-->
<Nested on:my-event />
</div>
<style>
.parent{
background-color:yellow;
padding:10px;
}
</style>
However, there is a workaround for this issue! We can create our own custom event dispatcher using the Custom Event API like this:
Nested.svelte
<script>
let ref;
const handleClick = ()=>{
const event = new CustomEvent('my-event', {
detail: {
content: 'nested component is clicked'
},
bubbles: true
});
ref.dispatchEvent(event);
}
</script>
<div class="nested" bind:this={ref} on:click={handleClick}>
nested component
</div>
<style>
.nested{
color:white;
background-color:blue;
}
</style>
Using the new CustomEvent()
constructor, we can create a native custom event and we can also set the bubbles
parameter to true
to allow the custom event to bubble.
Better yet, my HOD pointed out the custom_event
function from svelte/internal
. This function wraps Custom Event API and can also be used to dispatch custom events that can bubble:
Nested.svelte
<script>
import { custom_event } from 'svelte/internal';
let ref;
const handleClick = ()=>{
const event = custom_event('my-event', 'nested component is clicked', true);
ref.dispatchEvent(event);
}
</script>
<div class="nested" bind:this={ref} on:click={handleClick}>
nested component
</div>
<style>
.nested{
color:white;
background-color:blue;
}
</style>
Top comments (1)
In the Svelte source code there is a deprecated code segment, so I think the Custom Event API is the right choice.
Svelte code:
github.com/sveltejs/svelte/blob/62...
Depraction warning:
developer.mozilla.org/en-US/docs/W...