shadow DOM 만드는 법
<div class="mordor"></div>
<script>
document.querySelector('mordor').attachShadow({mode : 'open'});
document.querySelector('mordor').shadowRoot.innerHTML = '<p>심연에서왔도다</p>'
</script>
이러면 <div> 안에 몰래 <p>를 숨길 수 있음
1. 우선 attachShadow() 라는걸 써서 shadowRoot 라는 공간을 하나 만들어주고
2. shadowRoot 여기에 원하는 html 넣으면 숨겨짐
Web Component의 단점 : 스타일 오염
class 클래스 extends HTMLElement {
connectedCallback() {
this.innerHTML = `<label>이름을 입력하쇼</label><input>
<style> label { color : red } </style>`
}
}
customElements.define("custom-input", 클래스);
요따구로 코드짜면 다른 labael 태그도 오염됨
<custom-input></custom-input>
<label>왜 나까지 빨개짐?</label>
Component 한거 말고 다른 label 까지 오염됨요
이럴때 shadow DOM 쓰라고 만들어논듯..
왜냐면 shadow DOM은 자기만 해당되고 밖에 영향을 끼치지 않으니까
Web Component + shadow DOM
class 클래스 extends HTMLElement {
connectedCallback() {
this.attachShadow({mode : 'open'}); //shadow 공간 만들고
this.shadowRoot.innerHTML = `<label>이름을 입력하쇼</label><input>
<style> label { color : red } </style>` //shadow공간에 집어넣으면 다른 애들은 영향x
}
}
customElements.define("custom-input", 클래스);
<custom-input></custom-input>
<label>오 이제 바깥건 안빨개짐</label>
스타일과 태그들을 전부 shadow DOM으로 집어넣어놨더니
진짜 다른 태그들 스타일을 오염시키지 않음
그래서 대부분 Web Component 만들 때 shadow DOM을 활용하는듯
이것이 진정한 html 모듈화 개발 !
html 임시보관함 template 태그
컴포넌트 만들때 html 길어지면 너무 더러워보일듯
그래서 template태그안에 잠깐 쳐박아두고 할 수 있다
<custom-input></custom-input>
<template id="template1">
<label>이메일을 입력하쇼</label><input>
<style>label { color : red }</style>
</template>
<script>
class 클래스 extends HTMLElement {
connectedCallback() {
this.attachShadow({mode : 'open'});
this.shadowRoot.append(template1.content.cloneNode(true));
}
}
customElements.define("custom-input", 클래스);
</script>
템플릿 특징
템플릿 태그에 들어있는건 html에 보이지 않음
그래서 거기 보관하는 용도로만 사용하고
this.shadowRoot.append(template1.content.cloneNode(true)) 이런식으로 집어넣음 된다
이러면 html 길어져도 이쁘게 코드 짤 수 있을듯..
shadow DOM에 이벤트 리스너 부착할라믄
<custom-input></custom-input>
<template id="template1">
<label>이메일을 입력하쇼</label><input>
<style>label { color : red }</style>
</template>
<script>
class 클래스 extends HTMLElement {
connectedCallback() {
this.attachShadow({mode : 'open'});
this.shadowRoot.append(template1.content.cloneNode(true));
let el = this.shadowRoot.querySelector('label');
el.addEventListener('click', function(){
console.log('클릭함')
})
}
}
customElements.define("custom-input", 클래스);
</script>
뭐 부착해서 사용할 수 있다 정도만 보고 넘어가자