본문 바로가기
Front-end

[Javascript] Shadow DOM과 event.composed

by 발담그는블로그 2023. 8. 15.

DOM과 캡슐화

DOM(Document Of Model)은 HTML의 구조화된 문서 표현이다. DOM은 브라우저가 페이지에 어떤 것을 만들지 결정한다. 

HTML 문서의 모든 요소와 스타일로 이루어진 DOM은 하나의 큰 글로벌 범위 내에 있다.

이 중 몇몇 요소들은 글로벌에 영향을 받지 않는 즉, 완전한 캡슐화를 필요로 하는 요소들도 있다. 

 

<iframe scrolling="no" frameborder="0" allowtransparency="true" src="https://platform.twitter.com/widgets/follow_button.d30011b0f5ce05b98f24b01d3331b3c1.en.html#dnt=false&amp;id=twitter-widget-0&amp;lang=en&amp;screen_name=ireaderinokun&amp;show_count=false&amp;show_screen_name=true&amp;size=m&amp;time=1546395468133"></iframe>

예를 들어 iframe 태그는 전역CSS에 영향을 받지 않고 의도된 스타일로 나타나길 보장받을 수 있다. 

Shadow DOM이란 <iframe>과 같은 도구 없이도 캡슐화를 허용하도록 만들어졌다.

 

Shadow DOM이란

Shadow DOM은 DOM안의 DOM 이라고 표현할 수 있지만 제대로 표현하자면,

원래의 DOM 트리에서 완전히 분리된 고유의 요소와 스타일을 가진 DOM 트리다. 

 

Shadow DOM은 웹 작성자가 컨트롤 가능하도록 허용한 것은 얼마되지 않았지만, 실제로 사용된 것은 굉장히 오래전일이다. 

<input type="range">

다음 input 요소를 살펴보면 다음 Shadow DOM을 확인할 수 있다.

 

Shadow DOM 작동 방법

Shadow DOM 관련 용어는 다음과 같다.

  • Shadow host: shadow DOM이 부착되는 통상적인 DOM 노드.
  • Shadow tree: shadow DOM 내부의 DOM 트리.
  • Shadow boundary: shadow DOM이 끝나고, 통상적인 DOM이 시작되는 장소.
  • Shadow root: shadow 트리의 root 노드.

Shadow DOM을 만들기 위해선 Shadow host로 시작한다. Shadow host는 새로운 Shadow DOM을 붙일 원본 DOM의 일반 HTML 요소를 사용한다. 

<span class="shadow-host">
    <a href="https://twitter.com/ireaderinokun">
        Follow @ireaderinokun
     </a>
</span>

 

Host에 Shadow DOM을 붙이기 위해서는 attachShadowDOM() 메서드를 사용한다.

const shadowEl = document.querySelector(".shadow-host");
const shadow = shadowEl.attachShadow({mode: 'open'});

이 코드는 shadow host의 자식 요소인 빈 shadow root를 생성산다. <html> 요소가 DOM의 시작인 것처럼 shadow root는 shadow DOM의 시작점 역할을 한다. 일반 HTML 자식 요소는 검사기에서 확인될지라도 shadow root가 차지하면서 더 이상 페이지에 보이지 않게 된다.

 

다음으론 Shadow tree를 생성한다. 

const link = document.createElement("a");
link.href = shadowEl.querySelector("a").href;
link.innerHTML = `
    <span aria-label="Twitter icon"></span>
    ${shadowEl.querySelector("a").textContent}
`;

 

Event.composed

Shadow DOM과 작업하다보면, Custom Event로 생성한 이벤트가 Shadow DOM Boundary를 벗어나서 전파되지 않는 이슈를 마주하게 되는데, 이는 의도된 행동이다. 

Custom Event의 경우 기본 Event 인터페이스를 상속하며, composed를 기본값으로 false로 가지고 있다. 그렇기 때문에 Shadow root 상위로 전파되지 않는다. 

 

참고

- Shadow DOM은 무엇일까?

- DOM event.composed (shadow root 밖으로 이벤트 전파시키기)

 

 

반응형