Web과 프로그래밍 언어/JavaScript

[SVELTE] Actions-The use directive, Adding parameters

cosmicgy 2023. 3. 11. 14:43

Actions

 

- 사용 상황

  • 제3의 라이브러리와의 인터페이스
  • 이미지 로드의 속도가 느릴 때
  • 툴팁
  • custom event handler를 추가할 때

 

1. The use directive

 

// click_outsdie.js
export function clickOutside(node) {
    const handleClick = (event) => {
        if (!node.contains(event.target)) {
            node.dispatchEvent(new CustomEvent("outclick"));
        }
    };

    document.addEventListener("click", handleClick, true);

    return {
        destroy() {
            document.removeEventListener("click", handleClick, true);
        }
    };
}

 

<!-- App.svelte -->
<script>
    import { clickOutside } from "./click_outside.js";

    let showModal = true;
</script>

<button on:click={() => (showModal = true)}>Show Modal</button>
{#if showModal}
    <div class="box" use:clickOutside on:outclick={() => (showModal = false)}>
        Click outside me!
    </div>
{/if}

<style>
    .box {
        --width: 100px;
        --height: 100px;
        position: absolute;
        width: var(--width);
        height: var(--height);
        left: calc(50% - var(--width) / 2);
        top: calc(50% - var(--height) / 2);
        display: flex;
        align-items: center;
        padding: 8px;
        border-radius: 4px;
        background-color: #ff3e00;
        color: #fff;
        text-align: center;
        font-weight: bold;
    }
</style>

 

2. Adding parameters

js에서 액션을 만들고 use:액션 이름 ="파라미터" 형태로 사용

 

// longpress.js
export function longpress(node, duration) {
    let timer;

    const handleMousedown = () => {
        timer = setTimeout(() => {
            node.dispatchEvent(
                new CustomEvent('longpress')
            );
        }, duration);
    };

    const handleMouseup = () => {
        clearTimeout(timer)
    };

    node.addEventListener('mousedown', handleMousedown);
    node.addEventListener('mouseup', handleMouseup);

    return {
        update(newDuration) {
            duration = newDuration;
        },
        destroy() {
            clearTimeout(timer);
            node.removeEventListener('mousedown', handleMousedown);
            node.removeEventListener('mouseup', handleMouseup);
        }
    };
}

 

<!-- App.svelte -->
<script>
    import { longpress } from './longpress.js';

    let pressed = false;
    let duration = 2000;
</script>

<label>
    <input type=range bind:value={duration} max={2000} step={100}>
    {duration}ms
</label>

<button use:longpress={duration}
    on:longpress="{() => pressed = true}"
    on:mouseenter="{() => pressed = false}"
>press and hold</button>

{#if pressed}
    <p>congratulations, you pressed and held for {duration}ms</p>
{/if}

 

  • 라이프 사이클
function foo(node, bar) {
  // the node has been mounted in the DOM

  return {
    update(bar) {
      // the value of `bar` has changed
    },

    destroy() {
      // the node has been removed from the DOM
    }
  };
}
  • update : 액션이 선언된 DOM이 마운트 된 후 액션의 파라미터가 변경될 때마다 호출
  • destroy : 액션이 선언된 DOM 이 제거되기 직전에 호출, 할당받은 자원을 이 라이프 사이클 함수에서 해제해야 함
  • mount : 액션이 선언된 DOM이 마운트 된 후 동작해야 할 코드가 있다면 함수의 본문에 선언한다