Let's learn how to handle the event in Svelte.
- Event Bubbling : propagating the event from child to parent
- Event Capturing : propagating the event from parent to child
Inline Event Handler
DOM can have an inline event handler using on:click in Svelte.
<script lang="ts">
let text = 'Test';
</script>
<div on:click={() => (text += '.')}>
{text}
</div>
Multiple Event Handler
You can use multiple events with a single element.
<script lang="ts">
let count = 0;
function increase() {
count++;
}
function print() {
console.log(`count: ${count}`);
}
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>{count}</h1>
<button on:click={increase} on:click={print} on:click={currentTarget}>Test</button>
Event Modifiers
Svelte provides several event modifiers.
preventDefault
preventDefault modifier prevents the default action of the event.
<script lang="ts">
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>preventDefault</h1>
<a href="https://hdevstudy.tistory.com" target="_blank" on:click|preventDefault={currentTarget}>
HoYa's Tistory Blog
</a>
This hyperlink will not work because of the preventDefault modifier.
stopPropagation
stopPropagation modifier stops event propagation.
In other words, it doesn't propagate an event to the upper element.
<script lang="ts">
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>stopPropagation</h1>
<div on:click={currentTarget}>
<div on:click|stopPropagation={currentTarget}>Test</div>
</div>
passive and nonpassive
passive modifier improves scrolling performance on touch/wheel events. Svelte will add this automatically where it's safe to do so.
nonpassive modifier explicitly set "passive:false".
<script lang="ts">
function currentEvent(e) {
console.log(e);
}
</script>
<h1>passive</h1>
<div class="parent wheel" on:wheel|passive={currentEvent}>
<div class="child wheel" />
</div>
<style>
.parent {
width: 50px;
height: 50px;
background-color: tomato;
}
.parent.wheel {
overflow: auto;
}
.child.wheel {
height: 1000%;
}
</style>
capture
capture modifier captures the event of the child.
<script lang="ts">
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>capture</h1>
<div on:click|capture={currentTarget}>
<div on:click={currentTarget}>Test</div>
</div>
once
once modifier removes the event handler once executed.
<script lang="ts">
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>once</h1>
<a
href="https://hdevstudy.tistory.com"
target="_blank"
on:click|preventDefault|once={currentTarget}
>
HoYa's Tistory Blog
</a>
This hyperlink will not work at first, but it work after then.
And, currentTarget() function is run once.
self
self modifier only triggers event handler if event target is itself.
<script lang="ts">
function currentTarget(e) {
console.log(e.currentTarget);
}
</script>
<h1>self</h1>
<div class="parent" on:click|self={currentTarget}>
<div class="child" />
</div>
<style>
.parent {
width: 50px;
height: 50px;
background-color: tomato;
}
.child {
width: 30px;
height: 30px;
background-color: teal;
}
</style>
Event Dispatcher
Svelte's component can generate events and pass the data to the parent component.
<!-- components/EventDispatcher.svelte -->
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function sendEvent() {
dispatch('fromChild1');
}
function sendEventWithData() {
dispatch('fromChild2', 7);
}
</script>
<div>
<button on:click={sendEvent}>Send Event 1</button>
<button on:click={sendEventWithData}>Send Event 2</button>
</div>
First, create a dispatcher.
Next, dispatch your own event.
you can pass the data as well.
<script lang="ts">
import EventDispatcher from '../components/EventDispatcher.svelte';
function currentEvent(e) {
console.log(e);
}
</script>
<EventDispatcher on:fromChild1={currentEvent} on:fromChild2={currentEvent} />
You can handle the passed event by on: directive.
And, you can get the data from the detail field of the event.
Event Forwarding
The events of components aren't bubbling unlike the events of DOM elements.
Therefore, you have to send it manually.
<!-- components/EventChild.svelte -->
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<h2>Child</h2>
<button on:click={() => dispatch('childEvent', { name: 'HoYa', age: 18 })}>
Child
</button>
For example, I created a custom event with object literal.
<!-- components/EventParent.svelte -->
<script lang="ts">
import EventChild from './EventChild.svelte';
</script>
<h1>Parent</h1>
<EventChild on:childEvent />
Just specify the event via on: directive from the child component.
<script lang="ts">
import EventParent from '../components/EventParent.svelte';
function currentEvent(e) {
console.log(e);
}
</script>
<EventParent on:childEvent={currentEvent} />
Then, it can be passed to the upper component.
The object in the event is also included.
'Web > JavaScript' 카테고리의 다른 글
[Svelte] Context (0) | 2021.12.04 |
---|---|
[Svelte] Action (0) | 2021.12.02 |
[Svelte] Slot (0) | 2021.11.28 |
[Svelte] Props (0) | 2021.11.27 |
[Svelte] Reactivity (0) | 2021.11.25 |
댓글