-
Shadow DOMDOM/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: …})를 호출하면 섀도우 트리가 생성됩니다. 두 가지 제한 사항이 있습니다.
- 하나의 element 는 하나의 섀도우 루트만 만들 수 있습니다.
- '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은 기본 문서와 강력하게 구분됩니다.
- Shadow DOM 요소는 light DOM의 querySelector에 표시되지 않습니다. 특히, Shadow DOM 요소는 light DOM의 ID와 충돌하는 ID를 가질 수 있습니다. ID는 Shadow tree 내에서만 고유해야 합니다.
- 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>
- 문서의 스타일은 그림자 트리에 영향을 주지 않습니다.
- 하지만 내부 스타일이 작동합니다.
- 섀도우 트리의 요소를 가져오려면 트리 내부에서 쿼리해야 합니다.
반응형'DOM > HTML5' 카테고리의 다른 글
대체 텍스트 가이드 (1) 2022.10.05 대용량 이미지 분기 처리 (1) 2022.09.30 HTML 오디어 / 비디오 DOM 참조 | W3C (0) 2021.02.24