본문 바로가기
Web과 프로그래밍 언어/JavaScript

[SVELTE] Events - DOM events, Inline handlers, Event modifiers, Component events, Event forwarding, DOM event forwarding

by cosmicgy 2023. 3. 8.

 

Events

on 지시어를 사용해 요소의 모든 이벤트를 수신할 수 있다.

 

<script>
    let m = { x: 0, y: 0 };

    function handleMousemove(event) {
        m.x = event.clientX;
        m.y = event.clientY;
    }
</script>

<div on:mousemove={handleMousemove}>
    The mouse position is {m.x} x {m.y}
</div>

<style>
    div { width: 100%; height: 100%; }
</style>

 

또한 이벤트 핸들러를 인라인으로 선언할 수도 있다.

 

 <script>
    let m = { x: 0, y: 0 };
</script>

<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}">
    The mouse position is {m.x} x {m.y}
</div>

<style>
    div { width: 100%; height: 100%; }
</style>

 

돔 이벤트 핸들러는 동작을 변경하는 수정자를 가질 수 있다. 예를들어 once 수정자가 있는 핸들러는 한번만 실행된다.

 

<script>
    function handleClick() {
        alert('no more alerts')
    }
</script>

<button on:click|once={handleClick}>
    Click me
</button>

 

컴포넌트는 이벤트를 전달할 수 있다. 그렇게 하려면 이벤트 디스패쳐(dispatcher)를 만들어야 한다.

cf) 이벤트 디스패쳐 : 이벤트 디스패처는 하나의 액터가 이벤트를 디스패치하고 해당 이벤트를 리스닝하는 다른 액터가 알림을 받는 액터 커뮤니케이션 메서드입니다.

 

<!-- App.svelte -->
<script>
    import Inner from './Inner.svelte';

    function handleMessage(event) {
        alert(event.detail.text);
    }
</script>

<Inner on:message={handleMessage}/>

<!-- Inner.svelte -->
<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        dispatch('message', {
            text: 'Hello!'
        });
    }
</script>

<button on:click={sayHello}>
    Click to say hello
</button>

 

돔이벤트와 달리 컴포넌트 이벤트는 버블링되지 않는다. 깊게 중첩된 컴포넌트에서 이벤트를 수신하려면 중간 컴포넌트가 이벤트를 전달해야 한다. 값이 없는 on:message 이벤트 지시문은 '모든 메시지 이벤트 전달'을 의미한다.

 

<!-- App.svelte -->
<script>
    import Outer from './Outer.svelte';

    function handleMessage(event) {
        alert(event.detail.text);
    }
</script>

<Outer on:message={handleMessage}/>

<!-- Inner.svelte -->
<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        dispatch('message', {
            text: 'Hello!'
        });
    }
</script>

<button on:click={sayHello}>
    Click to say hello
</button>

<!-- Outer.svelte -->
<script>
    import Inner from './Inner.svelte';
</script>

<Inner on:message/>

 

이벤트 전달은 돔 이벤트에서도 작동한다.

 

<!-- App.svelte -->
<script>
    import CustomButton from './CustomButton.svelte';

    function handleClick() {
        alert('Button Clicked');
    }
</script>

<CustomButton on:click={handleClick}/>

<!-- CustomButton.svelte -->
<button on:click>
    Click me
</button>

<style>
    button {
        background: #E2E8F0;
        color: #64748B;
        border: unset;
        border-radius: 6px;
        padding: .75rem 1.5rem;
        cursor: pointer;
    }
    button:hover {
        background: #CBD5E1;
        color: #475569;
    }
    button:focus {
        background: #94A3B8;
        color: #F1F5F9;
    }
</style>