ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Shadow DOM
    DOM/HTML5 2022. 12. 9. 13:57
    반응형

    [출처: https://javascript.info/shadow-dom]

    Shadow DOM

    Shadow DOM은 캡슐화를 위해 사용됩니다. 이를 통해 구성 요소는 고유한 "섀도우" DOM ​​트리를 가질 수 있으며 기본 문서에서 실수로 액세스할 수 없으며 로컬 스타일 규칙 등을 가질 수 있습니다.

    Built-in shadow DOM

    복잡한 브라우저 컨트롤이 어떻게 생성되고 스타일이 지정되는지 생각해 본 적이 있습니까? (예 <input type="range">)

    브라우저는 그것들을 그리기 위해 내부적으로 DOM/CSS를 사용합니다. 그 DOM 구조는 일반적으로 우리에게 숨겨져 있지만 개발자 도구에서 볼 수 있습니다. 예를 들어 Chrome에서는 개발자 도구에서 "Show user agent shadow DOM" 옵션을 활성화해야 합니다.

     

    그러면 <input type="range">다음과 같이 보입니다.

    위에 #shadow-root에 보이는 것을 "shadow DOM"이라고 합니다.

     

    일반 JavaScript 호출 또는 선택기로 내장된 Shadow DOM 요소를 가져올 수 없습니다. 이들은 일반 자식이 아니라 강력한 캡슐화 기술입니다. 위의 예에서 유용한 속성 "pseudo"를 볼 수 있습니다. 그것은 비표준이며 역사적인 이유로 존재합니다. 다음과 같이 CSS와 함께 스타일 하위 요소를 사용할 수 있습니다.

    <style>
    /* make the slider track red */
    input::-webkit-slider-runnable-track {
      background: red;
    }
    </style>
    
    <input type="range">

    Shadow tree

    DOM 요소에는 두 가지 유형의 DOM 하위 트리가 있을 수 있습니다.

    • Light tree – HTML 자식으로 구성된 일반 DOM 하위 트리입니다. 이전 장에서 본 모든 하위 트리는 "가벼움"이었습니다.
    • Shadow tree – HTML에 반영되지 않은 숨겨진 DOM 하위 트리로, 엿보는 눈에서 숨겨집니다.

     

    element에 둘 다 있는 경우 브라우저는 그림자 트리만 렌더링합니다. 그러나 우리는 Shadow tree와 Light tree 사이에도 일종의 구성을 설정할 수 있습니다. 구성 요소 내부를 숨기고 구성 요소 로컬 스타일을 적용하기 위해 사용자 지정 요소에서 Shadow tree를 사용할 수 있습니다.



    예를 들어 이 <show-hello> 요소는 Shadow tree에서 내부 DOM을 숨깁니다.

    <script>
    customElements.define('show-hello', class extends HTMLElement {
      connectedCallback() {
        const shadow = this.attachShadow({mode: 'open'});
        shadow.innerHTML = `<p>
          Hello, ${this.getAttribute('name')}
        </p>`;
      }
    });
    </script>
    
    <show-hello name="John"></show-hello>

    이것이 Chrome 개발 도구에서 DOM이 보이는 방식이며 모든 콘텐츠는 "#shadow-root" 아래에 있습니다.

    먼저 elem.attachShadow({mode: …})를 호출하면 섀도우 트리가 생성됩니다. 두 가지 제한 사항이 있습니다.

    1. 하나의 element 는 하나의 섀도우 루트만 만들 수 있습니다.
    2. 'elem'은 사용자 정의 요소이거나 “article”, “aside”, “blockquote”, “body”, “div”, “footer”, “h1…h6”, “header”, “main” “nav”, “p”, “section”, or “span” 이며, <img>와 같은 다른 요소는 Shadow tree를 호스트할 수 없습니다.

     

    'mode' 옵션은 캡슐화 수준을 설정합니다. 다음 두 값 중 하나를 가져야 합니다.

    • "open" – Shadow root를 elem.shadowRoot로 사용할 수 있습니다.
      모든 코드는 요소의 섀도우 트리에 액세스할 수 있습니다.
    • "closed" – elem.shadowRoot는 항상 null입니다.

     

    우리는 attachShadow에 의해 반환된 참조에 의해서만 Shadow DOM에 액세스할 수 있습니다(아마도 클래스 내부에 숨겨져 있을 것입니다). <input type="range">와 같은 브라우저 고유의 Shadow tree는 "closed" 이며, 액세스할 방법이 없습니다.

     

    attachShadow에 의해 반환되는 Shadow root는 element 와 같습니다. innerHTML 또는 DOM 메서드(예: append)를 사용하여 채울 수 있습니다. Shadow root가 있는 요소를 "Shadow tree host"라고 하며 Shadow tree host 속성으로 사용할 수 있습니다.

    // {mode: "open"}으로 가정하고, 그렇지 않으면 elem.shadowRoot는 null입니다.
    alert(elem.shadowRoot.host === elem); // true

    Encapsulation

    Shadow DOM은 기본 문서와 강력하게 구분됩니다.

    1. Shadow DOM 요소는 light DOM의 querySelector에 표시되지 않습니다. 특히, Shadow DOM 요소는 light DOM의 ID와 충돌하는 ID를 가질 수 있습니다. ID는 Shadow tree 내에서만 고유해야 합니다.
    2. Shadow DOM에는 자체 스타일시트가 있습니다. 외부 DOM의 스타일 규칙은 적용되지 않습니다.

     

    예를 들어

    <style>
      /* 문서 스타일은 #elem(1) 내부의 shadow tree에 적용되지 않습니다. */
      p { color: red; }
    </style>
    
    <div id="elem"></div>
    
    <script>
      elem.attachShadow({mode: 'open'});
        // shadow tree 는 고유 스타일이 있습니다. (2)
      elem.shadowRoot.innerHTML = `
        <style> p { font-weight: bold; } </style>
        <p>Hello, John!</p>
      `;
    
      // <p> 는 shadow tree 내부의 쿼리에서만 볼 수 있습니다. (3)
      alert(document.querySelectorAll('p').length); // 0
      alert(elem.shadowRoot.querySelectorAll('p').length); // 1
    </script>
    1. 문서의 스타일은 그림자 트리에 영향을 주지 않습니다.
    2. 하지만 내부 스타일이 작동합니다.
    3. 섀도우 트리의 요소를 가져오려면 트리 내부에서 쿼리해야 합니다.
    반응형

    'DOM > HTML5' 카테고리의 다른 글

    대체 텍스트 가이드  (1) 2022.10.05
    대용량 이미지 분기 처리  (1) 2022.09.30
    HTML 오디어 / 비디오 DOM 참조 | W3C  (0) 2021.02.24

    댓글

Luster Sun