정보실

웹학교

정보실

html Shadow DOM v1 이해(1)

본문

그림자 DOM은 슈퍼 히어로 영화의 악당이 아닙니다. DOM의 어두운 면도 아닙니다. 섀도 DOM은 단순히 문서 객체 모델 (또는 DOM)에서 트리 캡슐화 부족을 해결하는 방법입니다.


웹 페이지가 외부 소스의 데이터와 위젯을 사용하는 것이 일반적입니다. 캡슐화가 없으면 스타일이 HTML의 원치 않는 부분에 영향을 미쳐 개발자가 지나치게 특정한 선택기와 !important을 사용하여 스타일 충돌을 피할 수 있습니다.


https://blog.logrocket.com/understanding-shadow-dom-v1-fa9b81ebe3ac/ 


그러나 이러한 노력은 큰 프로그램을 작성할 때 효과적이지 않은 것으로 보이며 개발 시간의 상당 부분이 CSS 및 JavaScript 충돌을 방지하는 데 낭비됩니다. Shadow DOM API는 DOM 트리를 캡슐화하는 메커니즘을 제공하여 이러한 문제와 다른 문제를 해결하는 것을 목표로 합니다.


Shadow DOM은 웹 구성 요소를 만드는 데 사용되는 기본 기술 중 하나입니다. 다른 두 가지는 사용자 지정 요소와 HTML 템플릿입니다. 웹 컴포넌트의 스펙은 원래 웹 위젯 개발을 단순화하기 위해 Google에 의해 제안되었습니다.


세 가지 기술이 함께 작동하도록 설계되었지만 각 기술을 개별적으로 사용할 수 있습니다. 이 튜토리얼의 범위는 shadow DOM으로 제한됩니다.


DOM이란 무엇입니까? 


섀도우 DOM을 만드는 방법을 알아보기 전에 DOM이 무엇인지 이해하는 것이 중요합니다. W3C DOM (Document Object Model)은 HTML 및 XML 문서에 저장된 정보를 표시하고 조작하기 위한 플랫폼 및 언어 중립적 API (Application Programming Interface)를 제공합니다.


프로그래머는 DOM을 사용하여 요소 및 컨텐츠에 액세스, 추가, 삭제 또는 변경할 수 있습니다. DOM은 웹 페이지를 트리 구조로 취급합니다. 각 분기는 노드로 끝나고 각 노드는 객체를 보유하며 JavaScript와 같은 스크립팅 언어를 사용하여 수정할 수 있습니다. 다음 HTML 문서를 고려하십시오.


<html>
  <head>
    <title>Sample document</title>
  </head>
  <body>
    <h1>Heading</h1>
    <a href="https://example.com">Link</a>
  </body>
</html>

이 HTML의 DOM 표현은 다음과 같습니다.


1*bM6Ql5lImhMD3NCTuiF68g.png?resize=1117%2C883&ssl=1 


이 그림의 모든 상자는 노드입니다. 


DOM의 일부를 설명하는 데 사용되는 용어는 실제 세계의 가계도와 유사합니다.

  • 주어진 노드보다 한 레벨 위에 있는 노드는 해당 노드의 부모입니다.
  • 주어진 노드 아래의 한 수준 아래에 있는 노드는 해당 노드의 자식입니다.
  • 부모가 같은 노드는 형제입니다
  • 부모와 조부모를 포함하여 주어진 노드 위의 모든 노드를 해당 노드의 조상이라고 합니다.
  • 마지막으로 주어진 노드 아래의 모든 노드를 해당 노드의 자손이라고 합니다.


노드의 유형은 나타내는 HTML 요소의 종류에 따라 다릅니다. HTML 태그를 요소 노드라고 합니다. 중첩 태그는 요소 트리를 형성합니다. 요소 내의 텍스트를 텍스트 노드라고 합니다. 텍스트 노드에는 자식이 없을 수 있습니다. 나무의 잎으로 생각할 수 있습니다.


트리에 액세스하기 위해 DOM은 프로그래머가 문서의 내용과 구조를 수정할 수 있는 일련의 메소드를 제공합니다. 예를 들어 document.createElement('p');를 작성할 때 DOM에서 제공하는 메소드를 사용하고 있습니다. DOM이 없으면 JavaScript는 HTML 및 XML 문서의 구조를 이해하지 못합니다.


다음 JavaScript 코드는 DOM 메소드를 사용하여 두 개의 HTML 요소를 작성하고 하나를 다른 요소 안에 중첩하고 텍스트 컨텐츠를 설정하고 문서 본문에 추가하는 방법을 보여줍니다.


const section = document.createElement('section');
const p = document.createElement('p');

p.textContent = 'Hello!';

section.appendChild(p);

document.body.appendChild(section);

이 JavaScript 코드를 실행 한 결과 DOM 구조는 다음과 같습니다.


<body>
  <section>
    <p>Hello!</p>
  </section>
</body>

그림자 DOM이란 무엇입니까? 


캡슐화는 객체 지향 프로그래밍의 기본 기능으로, 프로그래머가 객체의 일부 구성 요소에 대한 무단 액세스를 제한 할 수 있습니다.


이 정의에 따라 객체는 데이터와 상호 작용할 수 있는 방법으로 공개적으로 액세스 가능한 메서드 형식의 인터페이스를 제공합니다. 이러한 방식으로 객체의 내부 표현은 객체의 정의 외부에서 직접 액세스 할 수 없습니다.


Shadow DOM은이 개념을 HTML로 가져옵니다. 숨겨진 개별 DOM을 요소에 연결할 수 있으므로 HTML 및 CSS에 대한 로컬 범위를 지정할 수 있습니다. 이제 이름 충돌에 대해 걱정할 필요 없이 보다 일반적인 CSS 선택기를 사용할 수 있으며 스타일이 더 이상 누출되거나 의도하지 않은 요소에 적용되지 않습니다.


실제로 Shadow DOM API는 HTML 구조, 스타일 및 동작을 코드의 다른 부분과 분리하는 데 라이브러리 및 위젯 개발자가 필요로 하는 것입니다.


섀도우 루트는 섀도우 트리에서 최상위 노드입니다. 이것은 섀도우 DOM을 만들 때 일반 DOM 노드에 연결되는 것입니다. 섀도 루트가 연결된 노드를 섀도 호스트라고 합니다.


일반 DOM과 같은 방식으로 섀도우 루트에 요소를 연결할 수 있습니다. 섀도우 루트에 연결된 노드는 섀도우 트리를 형성합니다. 다이어그램은 이것을 명확하게 해야 합니다.


1*G35_koIDio_s94u57QzmZA.png?resize=1255%2C804&ssl=1 



light DOM이라는 용어는 보통 DOM을 shadow DOM과 구별하기 위해 사용됩니다. shadow DOM과 light DOM을 함께 논리 DOM이라고 합니다. 라이트 DOM이 그림자 DOM과 분리되는 지점을 그림자 경계라고 합니다. DOM 쿼리와 CSS 규칙은 그림자 경계의 다른쪽으로 이동할 수 없으므로 캡슐화가 생성됩니다.


그림자 DOM  만들기 


섀도 DOM을 만들려면 Element.attachShadow() 메서드를 사용하여 섀도 루트를 요소에 연결해야 합니다. 구문은 다음과 같습니다.


var shadowroot = element.attachShadow(shadowRootInit);

간단한 예를 살펴 보겠습니다.


<div id="host"><p>Default text</p></div>

<script>
  const elem = document.querySelector('#host');
     
  // attach a shadow root to #host
  const shadowRoot = elem.attachShadow({mode: 'open'});
     
  // create a <p> element
  const p = document.createElement('p');
     
  // add <p> to the shadow DOM
  shadowRoot.appendChild(p);
     
  // add text to <p> 
  p.textContent = 'Hello!';
</script>

이 코드는 shadow DOM 트리를 id가 host 인 div 요소에 연결합니다. 이 트리는 div의 실제 하위 요소와 별개이며 추가 된 항목은 호스팅 요소에 로컬입니다.


1*y2gTKKe8oJ9NOoi6t3lZ4Q.png?resize=840%2C197&ssl=1 

Chrome DevTools의 섀도우 루트. 


#host의 기존 요소가 섀도 루트로 어떻게 바뀌는 지 확인하십시오. shadow DOM을 지원하지 않는 브라우저는 기본 컨텐츠를 사용합니다.


이제 주 문서에 CSS를 추가 할 때 스타일 규칙은 그림자 DOM에 영향을 미치지 않습니다.


<div><p>Light DOM</p></div>
<div id="host"></div>

<script>
  const elem = document.querySelector('#host');
 
  // attach a shadow root to #host
  const shadowRoot = elem.attachShadow({mode: 'open'});
 
  // set the HTML contained within the shadow root
  shadowRoot.innerHTML = '<p>Shadow DOM</p>';
</script>

<style>
  p {color: red}
</style>

라이트 DOM에 정의 된 스타일은 그림자 경계를 넘을 수 없습니다. 결과적으로 light DOM의 단락 만 빨간색으로 바뀝니다.


1*suNI_ZRw7DTKw4qVglba2A.png?resize=699%2C256&ssl=1 


반대로 shadow DOM에 추가 한 CSS는 호스팅 요소에 로컬이며 DOM의 다른 요소에는 영향을 미치지 않습니다.


<div><p>Light DOM</p></div>
<div id="host"></div>

<script>
  const elem = document.querySelector('#host');
  const shadowRoot = elem.attachShadow({mode: 'open'});
 shadowRoot.innerHTML = `
    <p>Shadow DOM</p>
    <style>p {color: red}</style>`;

</script>

1*urR49nrpiy0bmGlY2Fdwmg.png?resize=699%2C256&ssl=1 


다음과 같이 스타일 규칙을 외부 스타일 시트에 넣을 수도 있습니다.


shadowRoot.innerHTML = `
  <p>Shadow DOM</p>
  <link rel="stylesheet" href="style.css">`;

shadowRoot가 연결된 요소에 대한 참조를 얻으려면 host 속성을 사용할 수 있습니다.


<div id="host"></div>

<script>
  const elem = document.querySelector('#host');
  const shadowRoot = elem.attachShadow({mode: 'open'});

  console.log(shadowRoot.host);    // => <div id="host"></div>
</script>

반대의 작업을 수행하고 요소가 호스팅하는 섀도우 루트에 대한 참조를 얻으려면 요소의 shadowRoot 속성을 사용하십시오.


<div id="host"></div>
 
<script>
  const elem = document.querySelector('#host');
  const shadowRoot = elem.attachShadow({mode: 'open'});

  console.log(elem.shadowRoot);    // => #shadow-root (open)
</script>







  • 트위터로 보내기
  • 페이스북으로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

페이지 정보

조회 72회 ]  작성일19-08-07 10:33

웹학교