Shadow DOM & template

Jian·2022년 9월 26일
0

JavaScript

목록 보기
20/27

📌 Shadow DOM이란?


숨겨져 있는 DOM. 개발자 도구 > Elements로 찾아 봐도 안 보인다.

Shadow DOM 보는 법
크롬 개발자도구 - 설정 - show user agent shadow DOM

📌 사용법


1. Shadow Root 생성

Shadow DOM을 생성할 공간인 Shadow Root을 만들어준다.


<div id='shadow'><div>
  
<script>
  document.querySelector('#shadow').attachShadow({ mode: 'open' })

2. 숨길 DOM 작성한다

document.querySelector('#shadow').shadowRoot.innerHTML = '<p>shadow</p>' // Shadow root내 shadow dom을 생성한다.

📌 Web Elements에 적용하기


Web Elements에 작성 시 장점

해당 태그의 독립성을 유지할 수 있다.

Web Component에 style 넣고 싶을 때, 해당 태그의 코드 안에 style코드 직접 작성하면 해당 태그 외에 다른, 동일한 태그에도 적용되어 버린다.
(Web Components인 Label 태그에 style 적용했는데 Web Components가 아닌 일반 label 태그에도 속성 적용되는 문제)

이 때 shadow DOM 이용하면, 해당 Web Elements 태그 내에서만 적용되게 할 수 있다.

🚨 단, Shadow DOM 외부의 inherit되는 속성은 Shadow DOM에 적용될 수는 있다.

Web Components에 사용하기

Web Components를 생성하는 Class 내부에 작성해준다.

<script>
 class Cls extends HTMLElement {
  connectedCallback() {
    let name = this.getAttribute('name')

    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `
      <label>인풋명</label><input>
         <style>label {color : red}</style>
      </template> `
    })
  }

c.f. 위 코드에서 this는 Class로부터 생성되는 instance를 뜻한다.

template : shadow 내용 분리하기

특정 HTML을 저장할 수 있게 하는 태그이다.
여기 작성한 코드는 렌더링되지 않는다.

shadow DOMWeb Components에 바로 작성하면 코드 가독성이 떨어지므로
template 태그로 분리하여 작성하면 유지관리가 용이해진다.

<body>
 <template id = "temp1">
    <label>인풋명</label><input>
       <style>label {color : red}</style>
  </template>
  class Cls extends HTMLElement {
      connectedCallback() {
        let name = this.getAttribute('name')

        this.attachShadow({ mode: 'open' });
        
        // template 태그 가져온다
        this.shadowRoot.append(temp1.content.cloneNode(true));
      }

Shadow DOM에 이벤트리스너 달기

Web Components의 Class 내부에서 이벤트리스너 달 DOM을 선택 후 아래와 같이 작성해준다.

 class Cls extends HTMLElement {
      connectedCallback() {
        let name = this.getAttribute('name')

        this.attachShadow({ mode: 'open' });
        this.shadowRoot.append(temp1.content.cloneNode(true));

        let el = this.shadowRoot.querySelector('label');
        el.addEventListener('click', function(){
          console.log('click');
        })
      }
profile
개발 블로그

0개의 댓글