Svelte

[Svelte]input 태그 포커싱 처리

DevStory 2022. 8. 5.

input 태그 포커싱

Svelte에서 특정 컴포넌트 렌더링 후 또는 특정 조건에 의해 input 태그를 포커싱 처리하는 작업이 필요할 수 있습니다.

 

예를 들어, "input 태그 활성화" 버튼을 클릭하면 input 태그 활성화됨과 동시에 포커싱 처리되어야 합니다.

<script>
  let strValue = '';    
  let isInputElementView = false;
</script>

<button on:click={() => isInputElementView = true}>
  input 태그 활성화
</button>

<button on:click={() => isInputElementView = false}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue}>
</div>
{/if}

[실행 결과]

"input 태그 활성화" 버튼을 클릭하면 input 태그가 활성화되지만, 포커싱 처리되지 않습니다.


방법 1. bind:this

Svelte에서 제공하는 bind 지시자에 this를 적용하면, DOM 요소를 참조할 수 있습니다.

 

script 영역에 input 태그를 참조하는 변수를 선언합니다. 그리고 input 태그의 bind:this에 새로 추가된 변수를 바인딩합니다.

 

button 태그의 click 이벤트를 처리하는 로직을 handleClick() 함수로 정의합니다. 함수에 전달된 값이 true인 경우 input 태그를 포커싱 처리합니다.

<script>
  let strValue = '';    
  let isInputElementView = false;
  let inputBind;

  const handleClick = (param) => {
    isInputElementView = param;
    if(param === true) {
      inputBind.focus();
    }
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue} bind:this={inputBind} />
</div>
{/if}

[실행 결과]

위 소스 코드를 적용하고 "input 태그 활성화" 버튼을 클릭했을 때, 콘솔에 출력된 TypeError를 볼 수 있습니다. 에러가 발생한 원인은 input 태그가 아직 DOM에 추가되지 않았는데 포커싱 처리했기 때문입니다.

 

svelte 패키지에서 제공하는 tick() 함수를 사용하여 input 태그가 DOM에 적용될 때까지 기다린 후 포커싱 처리하도록 소스 코드를 수정합니다.

<script>
  import {tick} from 'svelte'; // svelte 패키지 import 

  let strValue = '';    
  let isInputElementView = false;
  let inputBind;

  const handleClick = (param) => {
    isInputElementView = param;
    if(param === true) {
      tick().then(() => inputBind.focus()); // DOM 적용 후 포커싱 처리
    }
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue} bind:this={inputBind} />
</div>
{/if}

[실행 결과]

bind 지시자의 this를 사용하여 DOM 요소를 참조하는 방법은 아래 포스팅에서 확인할 수 있습니다.

 

[Svelte]DOM 요소 참조 방법

DOM 요소 참조 방법 이전 포스팅에서 bind 지시자를 사용하여 Form 요소의 value를 매핑하고 그룹화하는 방법을 소개하였습니다. [Svelte]bind 지시자 사용 방법 및 Form 요소 바인딩 bind 지시자 Svelte에서

developer-talk.tistory.com


방법 2. 생명주기 onMount 함수

두 번째 방법으로 스벨트의 생명주기 onMount() 함수를 사용합니다.

 

onMount() 함수를 사용하는 방법을 적용하려면 input 태그를 자식 컴포넌트로 생성합니다.

 

[부모 컴포넌트 - App.svelte]

<script>
  import {ChildInput} from './ChildInput.svelte'; // svelte 패키지 import 

  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
  <ChildInput />
{/if}

[자식 컴포넌트 - ChildInput.svelte]

<script>
  import {onMount} from 'svelte'; // svelte 패키지 import 

  let strValue = '';    
  let inputBind;

  onMount(() => {
    inputBind.focus();
  })
</script>

<div>
  <input type="text" bind:value={strValue} bind:this={inputBind} />
</div>

onMount() 함수는 Svelte의 생명주기 함수이며, 컴포넌트가 DOM에 추가될 때 호출됩니다.


방법 3. use 지시자

세 번째 방법으로 use 지시자를 사용합니다. bind:this와 생명주기 onMount() 함수도 좋은 방법이지만, use 지시자를 사용하면 더 쉽게 구현할 수 있습니다.

 

svelte에서 액션(Action)은 DOM 요소가 DOM에 추가될 때 실행되는 함수입니다. 액션은 use 지시자에 등록할 수 있습니다.

 

액션에 전달되는 인자는 액션을 호출하는 DOM 노드입니다. 전달된 인자에서 focus() 함수를 호출하여 input 태그를 포커싱 처리합니다.

<script>
  let strValue = '';    
  let isInputElementView = false;

  const handleClick = (param) => {
    isInputElementView = param;
  }

  const inputElementOnFocus = (element) => {
    element.focus();
  }
</script>

<button on:click={() => handleClick(true)}>
  input 태그 활성화
</button>

<button on:click={() => handleClick(false)}>
  input 태그 비활성화
</button>

{#if isInputElementView}
<div>
  <input type="text" bind:value={strValue} use:inputElementOnFocus />
</div>
{/if}
반응형

댓글