HTML <template>

jh·2023년 11월 19일

template

template 은 페이지를 불러온 순간 즉시 그려지지는 않지만, 이후 JS를 사용해 인스턴스를 생성할 수 있는 HTML 코드를 담을 방법을 제공합니다

해당 컨텐츠를 나중에 사용하기 위해 잠시 담아놓는 컨테이너 역할을 하는 태그

 <template id="template">
      <form>
        <div class="form-control">
          <label for="title">Title</label>
          <input type="text" id="title" />
        </div>
        <div class="form-control">
          <label for="description">Description</label>
          <textarea id="description" rows="3"></textarea>
        </div>
        <div class="form-control">
          <label for="people">People</label>
          <input type="number" id="people" step="1" min="0" max="10" />
        </div>
        <button type="submit">ADD PROJECT</button>
      </form>
    </template>

template의 특성

  • 해당 html이 모두 렌더링 되어도 template의 컨텐츠들은 화면에 보이지 않는다
    개발자도구 캡처
  • 개발자도구로 조회해 보아도 해당 태그의 요소는 #document-fragment로 되어있어 컨텐츠를 조회할 수 없음

=> 페이지가 로드될 때 즉시 렌더링 되지 않기 때문에 사용자에게 보이지 않는 것
=> 아예 template 태그를 읽지 않고 건너뛰는건 아님 - 해당 태그를 읽기는 하지만, 유효성을 검증하기 위함이며 렌더링 하기 위함은 아님

  • console.dir을 이용해서 해당 태그를 찍어보면 content 라는 속성이 존재하고, 이 속성 값은 document-fragment , 즉 DocumentFragment
    로 만들어져 있으면서 template태그의 하위 노드들은 이 안에 담겨 있다는 걸 알 수 있다

사용법

  • 제일 먼저 해당 브라우저가 템플릿 속성을 지원하는지를 확인해야 한다
if("content" in document.createElement('template'))

해당 속성을 지원한다면, template DOM 요소를 선택하여 해당 태그의 content값을 복제한 후(인스턴스화) 필요한 다른 요소에 삽입하는 방식으로 사용하면 된다

const t = document.querySelector('#template')
const clone = document.importNode(t.content,true)
//해당 clone을 원하는 대로 변경 후, 다른 노드에 삽입

여기서 importNode 라는 메서드는 타겟 노드를 복사하는 메서드로 두번째 인자로 타겟 노드의 자식 요소들을 포함하여 복사할 것인지를 boolean 값으로 지정해줄 수 있다

  • 비슷한 메서드로 'cloneNode'가 존재, 이 메서드 또한 자식 요소들을 포함할 것인지를 지정해 줄 수 있다.
  • 노드를 복사하는 메서드들은 여러개 존재

이번에 vanilaJS로만 개발할 경우 조건부로 html 요소를 추가해야 할때가 존재했는데

  • 문자열로 지정해놓고 innerHTML을 통해 렌더링
    - 코드는 깔끔해지지만, 보안 이슈 존재
  • document.createElement()를 통해 만들기
    - DOM 조작에 따른 성능 문제(fragment 통해서 어느정도 해결 가능)
    - 코드가 지저분해짐(element 생성, child 추가 등등의 과정)
  • html 로드해놓고 display 속성 사용하여 화면에서 숨기기
    - 이렇게 할 수 없는 경우도 존재

보통 이 세 가지 방법 중 하나를 이용했는데, 다음에 리팩토링하면서 template도 이용해보면 좋을 것 같다.

0개의 댓글