ì¹ ì»´í¬ëí¸ì ì¤ìí 측면ì 캡ìíì ëë¤. 캡ìí를 íµí´ ë§í¬ì 구조, ì¤íì¼, ëìì ì¨ê¸°ê³ íì´ì§ì ë¤ë¥¸ ì½ëë¡ë¶í°ì ë¶ë¦¬íì¬ ê°ê¸° ë¤ë¥¸ ë¶ë¶ë¤ì´ ì¶©ëíì§ ìê² íê³ , ì½ëê° ê¹ëíê² ì ì§ë ì ìê² í©ëë¤. Shadow DOM APIë 캡ìíì íµì¬ íí¸ì´ë©°, ì¨ê²¨ì§ ë¶ë¦¬ë DOMì ììì ë¶ì°©íë ë°©ë²ì ì ê³µí©ëë¤. ì´ ë¬¸ìë Shadow DOM ì¬ì©ì 기본ì ë¤ë£¹ëë¤.
ì°¸ê³ : Shadow DOMì Firefox (63 ì´ì), Chrome, Opera, Safariìì 기본ì¼ë¡ ì§ìë©ëë¤. ìë¡ì´ Chromium 기ë°ì Edge (79 ì´ì) ëí Shadow DOMì ì§ìíë 구ë²ì Edgeë ê·¸ë ì§ ììµëë¤.
ì¤ì ë´ì© ë³´ê¸°ì´ ë¬¸ìë ì¬ë¬ë¶ì´ ì´ë¯¸ DOM (Document Object Model)ì ê°ë ì ìµìíë¤ê³ ê°ì í©ëë¤. DOMì´ë ë§í¬ì 문ììì ëíëë ì¬ë¬ ê°ì§ ììë¤ê³¼ í ì¤í¸ 문ìì´ì ëíë´ë ì°ê²°ë ë ¸ëë¤ì í¸ë¦¬ê°ì 구조ì ëë¤ (ì¹ ë¬¸ìì ê²½ì° ë³´íµ HTML 문ì). ìì ë¡ì, ë¤ìì HTML fragment를 ê³ ë ¤í´ ë³´ì¸ì.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Simple DOM example</title>
</head>
<body>
<section>
<img
src="dinosaur.png"
alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth." />
<p>
Here we will add a link to the
<a href="https://www.mozilla.org/">Mozilla homepage</a>
</p>
</section>
</body>
</html>
ì´ fragmentë ë¤ìì DOM 구조를 ìì±í©ëë¤.
Shadow DOMì ì¨ê²¨ì§ DOM í¸ë¦¬ê° íµìì ì¸ DOM í¸ë¦¬ì ìí ììì ë¶ì°©ë ì ìê² í©ëë¤. ì´ shadow DOM í¸ë¦¬ë shadow rootë¡ë¶í° ììëì´ ìíë 모ë ììì ìì ë¶ì°©ë ì ìì¼ë©°, ê·¸ ë°©ë²ì ì¼ë° DOMê³¼ ê°ìµëë¤.
Flattened Tree (for rendering): (ë ëë§ì ìí´) ííí´ì§ í¸ë¦¬
ììì¼ í ì¡°ê¸ì shadow DOM ì©ì´ê° ììµëë¤.
ë¹(é) shadow ë
¸ëì ì íí ê°ì ë°©ë²ì¼ë¡ shadow DOM ë´ì ë
¸ëì ìí¥ì ë¯¸ì¹ ì ììµëë¤. ì를 ë¤ìë©´ childrenì appendíê±°ë, í¹ì±ì ì¤ì íê±°ë, element.style.foo를 ì¬ì©í´ ê° ë
¸ë를 꾸민ë¤ê±°ë, <style>
ìì ë´ë¶ì ìë ì ì²´ shadow DOM í¸ë¦¬ì ì¤íì¼ì ì¶ê°íë ê²ì´ ììµëë¤. ì°¨ì´ë shadow DOM ë´ë¶ì ì½ë ì¤ ì무 ê²ë shadow DOM ì¸ë¶ì 모ë ê²ì ìí¥ì ì£¼ì§ ìëë¤ë ì ì¸ë°, ì´ë í¸ë¦¬í 캡ìí를 ê°ë¥ì¼ í©ëë¤.
shadow DOMì´ ì´ë¤ ë°©ë²ì¼ë¡ë ìë¡ì´ ê²ì´ ìëë¼ë ê²ì 주목íì¸ì. ë¸ë¼ì°ì ë¤ì ì´ê²ì 긴 ìê°ëì ì¬ì©í´ì¤ë©° ììì ë´ë¶ 구조를 캡ìííìµëë¤. ì를 ë¤ì´ 기본 ë¸ë¼ì°ì 컨í¸ë¡¤ì´ ë
¸ì¶ë <video>
ìì를 ìê°í´ ë³´ì¸ì. DOMìì ë³´ì´ë 모ë ê²ì <video>
ììì§ë§, ì´ê²ì ì¼ë ¨ì ë²í¼ë¤ê³¼ ë¤ë¥¸ 컨í¸ë¡¤ë¤ì ì´ê²ì shadow DOM ë´ë¶ì í¬í¨íê³ ììµëë¤. shadow DOM ëª
ì¸ìë ì ë§ë¤ì´ì ¸ ìì ì¬ë¬ë¶ì ì¤ì ë¡ ì¬ë¬ë¶ë§ì ì¬ì©ì ì ì ììì shadow DOMì ì¡°ìí ì ììµëë¤.
Element.attachShadow()
ë©ìë를 ì¬ì©íì¬ ì´ë í ìììë shadow rootì ë¶ì°©í ì ììµëë¤. ì´ ë©ìëë 매ê°ë³ìë¡ íëì ìµì
ì í¬í¨íë ìµì
ê°ì²´ë¥¼ ì·¨í©ëë¤. ê·¸ ìµì
ì´ë mode
ì´ë©°, open
í¹ì closed
ì ê°ì ê°ì§ëë¤.
let shadow = elementRef.attachShadow({ mode: "open" });
let shadow = elementRef.attachShadow({ mode: "closed" });
open
ì ë©ì¸ íì´ì§ ë§¥ë½ìì ìì±ë JavaScript를 ì¬ì©íì¬ shadow DOMì ì ê·¼í ì ììì ì미í©ëë¤. ì를 ë¤ìë©´ Element.shadowRoot
ìì±ì ì¬ì©íì¬ ì ê·¼í ì ììµëë¤.
let myShadowDom = myCustomElem.shadowRoot;
ë§ì½ mode: closed
ë¡ ì¬ì©ì ì ì ììì shadow rootì ë¶ì°©íë¤ë©´, ì¸ë¶ë¡ë¶í° shadow DOMì ì ê·¼í ì ìì ê²ì
ëë¤. myCustomElem.shadowRoot
ì null
ì ë°íí©ëë¤. ì´ê²ì <video>
ì ê°ì´ shadow DOMì í¬í¨íê³ ìë ë´ì¥ ììë¤ì ê²½ì°ì
ëë¤.
ì°¸ê³ : ì´ ë¸ë¡ê·¸ ê¸ì´ ë³´ì¬ì£¼ë¯, closedì¸ shadow DOMì ì°ííë ê²ì ì¬ì¤ ìë¹í ì½ê³ , shadow DOMì ìì í ì¨ê¸°ê¸° ìí ê·ì°®ì ì¼ì ì¢ ì¢ ê·¸ ì¼ì ê°ì¹ë³´ë¤ ë í½ëë¤.
ë§ì½ shadow DOMì ì¬ì©ì ì ì ììì ì¬ì©ì ì ì ìì ìì±ìì ì¼ë¶ë¡ì¨ ë¶ì°©íë¤ë©´ (ë¨ì°ì½ shadow DOMì ê°ì¥ ì ì©í ì ì©), ë¤ìê³¼ ê°ì´ í ê²ì ëë¤.
let shadow = this.attachShadow({ mode: "open" });
shadow DOMì ììì ë¶ì°©íì ë, shadow DOMì ì¡°ìíë ê²ì ë¨ì§ íµìì ì¸ DOM ì¡°ìì ì¬ì©ëë ê²ê³¼ ê°ì DOM API를 ì¬ì©íë ê²ì 문ì ì ëë¤.
let para = document.createElement("p");
shadow.appendChild(para);
// ë±ë±
ê°ë¨í ìì ì´í´ë³´ê¸°
ì´ì ì¬ì©ì ì ì ìì ë´ë¶ìì ìëíë shadow DOMì ìì°í기 ìí ê°ë¨í ìì ìì¼ë¡ ë¤ì´ê° ë´
ìë¤. <popup-info>
(ìë ìì ë ë³¼ ì ììµëë¤). ì´ê²ì ì´ë¯¸ì§ ìì´ì½ê³¼ í
ì¤í¸ 문ìì´ì ì·¨íê³ , ìì´ì½ì íì´ì§ì ë£ìµëë¤. ìì´ì½ì´ í¬ì»¤ì¤ëìì ë, ì´ê²ì í
ì¤í¸ë¥¼ íì
ì ë³´ ë°ì¤ì íìíì¬ ì¶ê°ì ì¸ ë§¥ë½ ë´ ì 보를 ì ê³µí©ëë¤. ì°ì , JavaScript íì¼ìì PopUpInfo
ë¼ë í´ëì¤ë¥¼ ì ìíëë°, ì´ í´ëì¤ë HTMLElement
를 íì¥í©ëë¤.
class PopUpInfo extends HTMLElement {
constructor() {
// íì super를 ìì±ììì 먼ì í¸ì¶í©ëë¤
super();
// ìì 기ë¥ì ì¬ê¸° ìì±í©ëë¤
...
}
}
í´ëì¤ ì ì ë´ë¶ìì ììì ìì±ì를 ì ìíëë°, ì´ë ì´ í´ëì¤ì ì¸ì¤í´ì¤ê° ì¸ì¤í´ì¤íëìì ë ììê° ê°ì§ 모ë 기ë¥ì ì ìí©ëë¤.
shadow root ìì±í기첫ë²ì§¸ë¡ shadow rootì ì¬ì©ì ì ì ììì ë¶ì°©í©ëë¤.
// shadow rootì ìì±í©ëë¤
let shadow = this.attachShadow({ mode: "open" });
shadow DOM 구조를 ìì±í©ëë¤
ë¤ìì¼ë¡, ëª ê°ì§ DOM ì¡°ìì ì¬ì©íì¬ ììì ë´ë¶ shadow DOM 구조를 ìì±í©ëë¤.
// spanë¤ì ìì±í©ëë¤
let wrapper = document.createElement("span");
wrapper.setAttribute("class", "wrapper");
let icon = document.createElement("span");
icon.setAttribute("class", "icon");
icon.setAttribute("tabindex", 0);
let info = document.createElement("span");
info.setAttribute("class", "info");
// í¹ì±ì ë´ì©ì ì·¨íê³ ê·¸ê²ì info span ë´ë¶ì ë£ìµëë¤
let text = this.getAttribute("data-text");
info.textContent = text;
// ìì´ì½ì ì½ì
í©ëë¤
let imgUrl;
if (this.hasAttribute("img")) {
imgUrl = this.getAttribute("img");
} else {
imgUrl = "img/default.png";
}
let img = document.createElement("img");
img.src = imgUrl;
icon.appendChild(img);
shadow DOM 꾸미기
ì´íì <style>
ìì를 ìì±íê³ shadow DOMì 꾸미기 ìí ëª ê°ì§ CSSë¡ style ìì를 ì±ìëë¤.
// shadow DOMì ì ì©í ëª ê°ì§ CSS를 ìì±í©ëë¤
let style = document.createElement("style");
style.textContent = `
.wrapper {
position: relative;
}
.info {
font-size: 0.8rem;
width: 200px;
display: inline-block;
border: 1px solid black;
padding: 10px;
background: white;
border-radius: 10px;
opacity: 0;
transition: 0.6s all;
position: absolute;
bottom: 20px;
left: 10px;
z-index: 3;
}
img {
width: 1.2rem;
}
.icon:hover + .info, .icon:focus + .info {
opacity: 1;
}`;
shadow DOMì shadow rootì ë¶ì°©í기
ë§ì§ë§ ë¨ê³ë ìì±ë 모ë ìì를 shadow rootì ë¶ì°©íë ê²ì ëë¤.
// ìì±ë ììë¤ì shadow domì ë¶ì°©í©ëë¤
shadow.appendChild(style);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
ì¬ì©ì ì ì ìì ì¬ì©í기
í ë² í´ëì¤ê° ì ìëê³ ëë©´, ìì를 ì¬ì©íë ê²ì ìì를 ì ìíë ê²ê³¼ íì´ì§ì ìì를 ì¶ê°íë ê²ë§í¼ì´ë ê°ë¨í©ëë¤. (íì´ì§ì ìì를 ì¶ê°íë ê²ì ì¬ì©ì ì ì ìì ì¬ì©í기ìì ì¤ëª ëììµëë¤).
// ìë¡ì´ ìì를 ì ìí©ëë¤
customElements.define("popup-info", PopUpInfo);
<popup-info
img="img/alt.png"
data-text="Your card validation code (CVC) is an extra
security feature â it is the last 3 or 4
numbers on the back of your card."></popup-info>
ë´ë¶ ì¤íì¼ ë ì¸ë¶ ì¤íì¼
ìì ìì ììë <style>
ìì를 ì¬ì©íì¬ Shadow DOMì ì¤íì¼ì ì ì©íì§ë§, ëì <link>
ììë¡ë¶í° ì¸ë¶ ì¤íì¼ìí¸ë¥¼ 참조í¨ì¼ë¡ì¨ ì¤íì¼ì ì ì©íë ê²ë ìë²½í ê°ë¥í©ëë¤.
ì를 ë¤ì´, popup-info-box-external-stylesheet ìì (ìì¤ ì½ëë ë³¼ ì ììµëë¤) ì ì½ë를 íì¸í´ ë³´ì¸ì.
// ì¸ë¶ ì¤íì¼ì shadow domì ì ì©í©ëë¤
const linkElem = document.createElement("link");
linkElem.setAttribute("rel", "stylesheet");
linkElem.setAttribute("href", "style.css");
// ìì±ë ìì를 shadow domì ì ì©í©ëë¤
shadow.appendChild(linkElem);
<link>
ììë shadow rootì íì¸í¸ë¥¼ ë§ì§ ìì, ì¤íì¼ìí¸ê° ë¡ë©ëë ëì ì¤íì¼ëì§ ìì ë´ì©ì ë²ì©ì (FOUC, flash of unstyled content) ì´ ìì ì ìë¤ë ê²ì 주ìíì¸ì.
ë§ì 모ë ë¸ë¼ì°ì ë¤ì ê³µíµ ë
¸ëë¡ë¶í° ë³µì ëìê±°ë ëì¼í í
ì¤í¸ë¥¼ ê°ì§ê³ ìë <style>
íê·¸ì ëí ìµì í를 구ííì¬ ì¤íì¼ íê·¸ê° íëì ë°±ì
ì¤íì¼ìí¸ë¥¼ ê³µì í ì ìê² í©ëë¤. ì´ ìµì íë¡ ì¸í´ ì¸ë¶ ì¤íì¼ê³¼ ë´ë¶ ì¤íì¼ì ì±ë¥ì ë¹ì·í ê²ì
ëë¤.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4