on:eventname
on:
지시어는 DOM 이벤트를 수신하는 데 사용됩니다.
<script lang="ts">
let count = 0;
function handleClick(event: MouseEvent) {
count += 1;
}
</script>
<button on:click={handleClick}>
count: {count}
</button>
핸들러는 인라인으로 선언할 수 있으며, 성능에 영향을 주지 않습니다.
<button on:click={() => (count += 1)}>
count: {count}
</button>
이벤트에 수정자를 추가할 수 있으며, |
문자로 구분합니다.
<form on:submit|preventDefault={handleSubmit}>
<!-- 제출 이벤트의 기본 동작을 방지하여 페이지가 새로고침되지 않도록 함 -->
</form>
사용할 수 있는 수정자는 다음과 같습니다:
preventDefault
—event.preventDefault()
를 호출하여 기본 동작을 막음stopPropagation
—event.stopPropagation()
을 호출하여 이벤트가 다음 요소에 도달하는 것을 방지stopImmediatePropagation
— 다른 리스너가 실행되지 않도록 방지passive
— 터치/휠 이벤트에서 스크롤 성능을 향상capture
— 버블링 단계 대신 캡처 단계에서 핸들러 실행once
— 핸들러가 한 번 실행된 후 제거됨self
— 이벤트 타겟이 해당 요소일 때만 핸들러 실행trusted
—event.isTrusted
가 참일 때만 핸들러 실행
이벤트 지시어는 값 없이 사용할 수도 있습니다. 이 경우 컴포넌트는 이벤트를 전달하게 됩니다.
<button on:click>컴포넌트가 클릭 이벤트를 발생시킴</button>
같은 이벤트에 대해 여러 리스너를 등록할 수도 있습니다.
<script lang="ts">
let counter = 0;
function increment() {
counter += 1;
}
function track(event: MouseEvent) {
trackEvent(event);
}
</script>
<button on:click={increment} on:click={track}>Click me!</button>
bind:property
bind:
지시어는 데이터가 자식에서 부모로 흐르도록 허용합니다. 대부분의 바인딩은 특정 요소에 적용됩니다.
<input bind:value={name} />
<textarea bind:value={text} />
<input type="checkbox" bind:checked={yes} />
숫자 입력값은 자동으로 숫자로 변환됩니다. 예를 들어, type="number"
가 있을 때 값이 비어 있거나 유효하지 않으면 null
이 됩니다.
<input type="number" bind:value={num} />
<input type="range" bind:value={num} />
<input>
요소에서 파일 선택을 위해 bind:files
를 사용할 수 있습니다. 이 속성은 읽기 전용입니다.
<label for="avatar">사진 업로드:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
이벤트와 함께 바인딩을 사용할 때, 정의된 순서에 따라 이벤트 핸들러가 호출될 때 바인딩된 변수 값에 영향을 미칩니다.
<script>
let value = 'Hello World';
</script>
<input
on:input={() => console.log('Old value:', value)}
bind:value
on:input={() => console.log('New value:', value)}
/>
<select>
요소에서도 바인딩할 수 있습니다.
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b}>b</option>
<option value={c}>c</option>
</select>
bind:this
DOM 노드에 대한 참조를 얻으려면 bind:this
를 사용합니다.
<script lang="ts">
import { onMount } from 'svelte';
let canvasElement: HTMLCanvasElement;
onMount(() => {
const ctx = canvasElement.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvasElement} />
class:name
class:
지시어는 조건에 따라 클래스를 토글하는 짧은 문법을 제공합니다.
<!-- 두 가지 방식은 동일 -->
<div class={isActive ? 'active' : ''}>...</div>
<div class:active={isActive}>...</div>
여러 클래스를 토글할 수도 있습니다.
<div class:active class:inactive={!active} class:isAdmin>...</div>
style:property
style:
지시어는 여러 스타일을 요소에 설정하는 짧은 문법을 제공합니다.
<!-- 두 가지 방식은 동일 -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
<!-- 변수 사용 가능 -->
<div style:color={myColor}>...</div>
<!-- 스타일 여러 개 설정 가능 -->
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
important
로 스타일을 표시할 수도 있습니다.
<div style:color|important="red">...</div>
use:action
use:
지시어는 요소가 생성될 때 호출되는 함수를 정의하는 데 사용됩니다.
<script lang="ts">
import type { Action } from 'svelte/action';
const foo: Action = (node) => {
return {
destroy() {
// 노드가 DOM에서 제거되었을 때 호출됨
},
};
};
</script>
<div use:foo />
액션은 매개변수를 가질 수 있으며, update
메서드가 반환되면 매개변수가 변경될 때마다 호출됩니다.
<script lang="ts">
export let bar;
const foo: Action = (node, bar) => {
return {
update(bar) {
// bar 값이 변경되었을 때 호출됨
},
destroy() {
// 노드가 DOM에서 제거되었을 때 호출됨
},
};
};
</script>
<div use:foo={bar} />
transition:fn
transition:
지시어는 요소가 DOM에 들어가거나 나갈 때 트랜지션 애니메이션을 적용하는 데 사용됩니다. 트랜지션은 상태 변화에 따라 요소가 추가되거나 제거될 때 트리거됩니다.
{#if visible}
<div transition:fade>페이드 인/아웃 애니메이션</div>
{/if}
트랜지션은 기본적으로 로컬입니다. 즉, 해당 트랜지션이 속한 블록이 생성되거나 파괴될 때만 실행됩니다.
{#if x}
{#if y}
<p transition:fade>y가 변경될 때만 페이드 인/아웃</p>
<p transition:fade|global>x 또는 y가 변경될 때 페이드 인/아웃</p>
{/if}
{/if}
트랜지션 매개변수
트랜지션도 액션과 마찬가지로 매개변수를 가질 수 있습니다.
{#if visible}
<div transition:fade={{ duration: 2000 }}>2초간 페이드 인/아웃</div>
{/if}
커스텀 트랜지션 함수
커스텀 트랜지션 함수도 사용할 수 있습니다. 트랜지션 함수는 CSS 애니메이션을 생성하거나 매 프레임마다 tick
함수를 호출할 수 있습니다.
<script lang="ts">
import { elasticOut } from 'svelte/easing';
function whoosh(
node: HTMLElement,
params: { delay?: number; duration?: number; easing?: (t: number) => number },
) {
const existingTransform = getComputedStyle(node).transform.replace('none', '');
return {
delay: params.delay || 0,
duration: params.duration || 400,
easing: params.easing || elasticOut,
css: (t, u) => `transform: ${existingTransform} scale(${t})`,
};
}
</script>
{#if visible}
<div in:whoosh>커스텀 트랜지션</div>
{/if}
css
함수는 애니메이션을 위해 0에서 1 사이의 값인 t
를 사용하고, u
는 1 - t
값으로 변환됩니다. CSS 애니메이션을 사용할 수 있다면, tick
대신 CSS 애니메이션을 사용하는 것이 성능 면에서 더 좋습니다.
transition
이벤트
트랜지션을 사용하는 요소는 표준 DOM 이벤트 외에도 추가적인 이벤트를 디스패치합니다. 트랜지션 관련 이벤트는 다음과 같습니다:
introstart
: 요소가 DOM에 들어갈 때 트랜지션이 시작됨introend
: 요소가 DOM에 들어갈 때 트랜지션이 끝남outrostart
: 요소가 DOM에서 나갈 때 트랜지션이 시작됨outroend
: 요소가 DOM에서 나갈 때 트랜지션이 끝남
이벤트를 수신할 수 있으며, 이를 통해 트랜지션 상태를 추적할 수 있습니다.
{#if visible}
<p
transition:fly={{ y: 200, duration: 2000 }}
on:introstart={() => (status = 'intro started')}
on:outrostart={() => (status = 'outro started')}
on:introend={() => (status = 'intro ended')}
on:outroend={() => (status = 'outro ended')}
>
Flies in and out
</p>
{/if}
in:fn
/ out:fn
in:
및 out:
지시어는 특정 상태에 따라 요소가 DOM에 들어가거나 나가는 트랜지션을 설정할 수 있습니다.
in:
은 요소가 DOM에 추가될 때 실행되는 트랜지션입니다.out:
은 요소가 DOM에서 제거될 때 실행되는 트랜지션입니다.
이 트랜지션들은 양방향 트랜지션이 아닌 단일 방향 트랜지션을 적용하며, 트랜지션 중단 시 트랜지션이 처음부터 다시 시작됩니다.
{#if visible}
<div in:fly out:fade>플라이 인, 페이드 아웃 트랜지션</div>
{/if}
animate:fn
animate:
지시어는 keyed each
블록에서 데이터가 재정렬될 때 요소에 애니메이션을 적용하는 데 사용됩니다. 이 애니메이션은 요소가 추가되거나 제거될 때가 아니라, 기존 데이터 항목이 재배치될 때 트리거됩니다.
{#each list as item, index (item)}
<li animate:flip>{{ item }}</li>
{/each}
애니메이션 함수는 커스텀 애니메이션을 만들 수 있으며, DOMRect
객체를 기반으로 요소의 시작 위치와 종료 위치를 처리합니다.
<script lang="ts">
import { cubicOut } from 'svelte/easing';
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
const d = Math.sqrt(dx * dx + dy * dy);
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
};
}
</script>
{#each list as item, index (item)}
<div animate:whizz>{{ item }}</div>
{/each}
애니메이션 함수는 from
과 to
값을 사용하여 요소의 이동과 변화를 계산합니다. css
함수는 CSS 애니메이션을 생성하고, tick
함수는 애니메이션 동안 매 프레임마다 호출됩니다.
tick
함수
tick
함수는 애니메이션 동안 호출되며, 애니메이션의 현재 진행 상태(t
와 u
)를 기반으로 요소의 상태를 업데이트할 수 있습니다.
<script lang="ts">
function typewriter(node: HTMLElement, { speed = 1 }: { speed?: number }) {
const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;
if (!valid) {
throw new Error(`이 트랜지션은 텍스트 노드가 하나인 요소에서만 작동합니다`);
}
const text = node.textContent;
const duration = text.length / (speed * 0.01);
return {
duration,
tick: (t) => {
const i = ~~(text.length * t);
node.textContent = text.slice(0, i);
},
};
}
</script>
{#if visible}
<p in:typewriter={{ speed: 1 }}>빠르게 타자 치는 효과</p>
{/if}
이 함수는 텍스트가 서서히 입력되는 효과를 생성하는 데 유용하며, tick
함수를 사용해 애니메이션 진행 상태를 기반으로 텍스트를 업데이트합니다.
Svelte의 트랜지션, 애니메이션 및 이벤트 핸들링은 웹 페이지와 애플리케이션에서 동적인 인터페이스를 구현하는 데 매우 유용합니다. 이를 통해 다양한 사용자 인터페이스 효과를 쉽게 적용하고, 애니메이션 및 상호작용을 손쉽게 추가할 수 있습니다.
'프로그래밍 > Web' 카테고리의 다른 글
svelte 번역 - 8 - Template Syntax / Special elements (1) | 2024.10.17 |
---|---|
svelte 번역 - 7 - Template Syntax / Component directives (0) | 2024.10.17 |
svelte 번역 - 5 - Template Syntax / Special tags (0) | 2024.10.17 |
svelte 번역 - 4 - Template Syntax / Logic blocks (0) | 2024.10.17 |
svelte 번역 - 3 - Template Syntax / Basic markup (0) | 2024.10.17 |
댓글