숨겨져 있는 DOM. 개발자 도구 > Elements로 찾아 봐도 안 보인다.
Shadow DOM 보는 법
크롬 개발자도구 - 설정 - show user agent shadow DOM
Shadow DOM을 생성할 공간인 Shadow Root
을 만들어준다.
<div id='shadow'><div>
<script>
document.querySelector('#shadow').attachShadow({ mode: 'open' })
document.querySelector('#shadow').shadowRoot.innerHTML = '<p>shadow</p>' // Shadow root내 shadow dom을 생성한다.
해당 태그의 독립성을 유지할 수 있다.
Web Component
에 style 넣고 싶을 때, 해당 태그의 코드 안에 style코드 직접 작성하면 해당 태그 외에 다른, 동일한 태그에도 적용되어 버린다.
(Web Components인 Label 태그에 style 적용했는데 Web Components가 아닌 일반 label 태그에도 속성 적용되는 문제)
이 때 shadow DOM 이용하면, 해당 Web Elements
태그 내에서만 적용되게 할 수 있다.
🚨 단, Shadow DOM 외부의 inherit되는 속성은 Shadow DOM에 적용될 수는 있다.
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를 뜻한다.
특정 HTML을 저장할 수 있게 하는 태그이다.
여기 작성한 코드는 렌더링되지 않는다.
shadow DOM
을 Web 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));
}
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');
})
}