Shadow DOM ã¯ã«ãã»ã«åã«å½¹ç«ã¡ã¾ããããã«ãããã³ã³ãã¼ãã³ãã¯ç¬èªã® âshadow(é ããåå¨ã®)â DOM ããªã¼ãæã¤ãã¨ãã§ãã¾ããããã¯ãã¡ã¤ã³ã® document ãã誤ã£ã¦ã¢ã¯ã»ã¹ããããã¨ãªãããã¼ã«ã«ã®ã¹ã¿ã¤ã«ã«ã¼ã«ãªã©ãæã¤ãã¨ãã§ãã¾ãã
çµã¿è¾¼ã¿ã® shadow DOM
è¤éãªãã©ã¦ã¶å¶å¾¡ãã©ã®ããã«ãã¦ä½æãããã¹ã¿ã¤ã«ããã¦ãããèãããã¨ã¯ããã§ããããï¼
ä¾ãã° <input type="range"> ã§ã:
ãã©ã¦ã¶ã¯ããããæç»ããããã«å é¨çã« DOM/CSS ã使ãã¾ãããã®DOMæ§é ã¯é常é ããã¦ãã¾ãããéçºè ãã¼ã«ã§è¦ããã¨ãã§ãã¾ããE.g. Chrome ã§ã¯éçºè ãã¼ã«ã§ âShow user agent shadow DOMâ ãªãã·ã§ã³ãæå¹ã«ããå¿ è¦ãããã¾ãã
<input type="range"> ã¯æ¬¡ã®ããã«è¦ãã¾ã:
#shadow-root ã®ä¸ã«è¦ããã®ã âshadow DOMâ ã¨å¼ã°ãã¦ãããã®ã§ãã
é常㮠JavaScript å¼ã³åºããã»ã¬ã¯ã¿ã§ã¯çµã¿è¾¼ã¿ã® shadow DOM è¦ç´ ãåå¾ãããã¨ã¯ã§ãã¾ããããããã¯é常ã®åã§ã¯ãªããå¼·åã«ã«ãã»ã«åãããæè¡ã§ãã
ä¸ã®ä¾ã§ã¯ã便å©ãªå±æ§ pseudo ã確èªã§ãã¾ããããã¯æ¨æºã§ã¯ããã¾ããããæ´å²çãªçç±ã§åå¨ãã¦ãã¾ããããã¯ã次ã®ããã« CSS ã§ã¹ã¿ã¤ã«ã®ãµãè¦ç´ ã¨ãã¦ä½¿ããã¨ãã§ãã¾ãã:
<style>
/* ã¹ã©ã¤ãã¼ã赤ã«ãã¾ã */
input::-webkit-slider-runnable-track {
background: red;
}
</style>
<input type="range">
ç¹°ãè¿ãã¾ãããpseudo ã¯éæ¨æºã®å±æ§ã§ããæç³»åçã«ã¯ããã©ã¦ã¶ã¯æåãã³ã³ããã¼ã«ãå®è£
ããããã«å
é¨çãªDOMæ§é ã試ã¿å§ãã¾ããããã®å¾ãshadow DOMã¯æ¨æºåãããéçºè
ãåæ§ã®ãã¨ãã§ããããã«ãªãã¾ããã
ä»å¾ã¯ãDOM specãä»ã®é¢é£ä»æ§ã«ããè¨è¿°ããã¦ãææ°ã® shadow DOM æ¨æºã使ç¨ãã¾ãã
Shadow tree
DOM è¦ç´ ã«ã¯2種é¡ã® DOM ã®ãµãããªã¼ãããã¾ãã:
- Light tree â HTMLã®åãããªããé常㮠DOM ãµãããªã¼ã§ããããã¾ã§ã®ãã£ãã¿ã¼ã§è¦ã¦ãããã¹ã¦ã®ãµãããªã¼ã¯ âlightâ ã§ããã
- Shadow tree â é ããã DOM ãµãããªã¼ã§ããHTML ã«ã¯åæ ãããã詮索好ããªç®ããã¯é ããã¦ãã¾ãã
è¦ç´ ã両æ¹ãå«ãã§ããå ´åããã©ã¦ã¶ã¯ shadow tree ã®ã¿ãã¬ã³ããªã³ã°ãã¾ããããããshadow ããªã¼ã¨ light ããªã¼ãçµã¿åããããã¨ãã§ãã¾ãã詳細ã«é¢ãã¦ã¯ããã£ãã¿ã¼ Shadow DOM ã¹ããã, ã³ã³ãã¸ã·ã§ã³ ã§èª¬æãã¾ãã
Shadow tree ã¯ãã«ã¹ã¿ã è¦ç´ ãä¸èº«ãã³ã³ãã¼ãã³ãã®å é¨ã«é ããããã³ã³ãã¼ãã³ããã¼ã«ã«ãªã¹ã¿ã¤ã«ãé©ç¨ããããã«ä½¿ããã¨ãã§ãã¾ãã
ä¾ãã°ããã® <show-hello> è¦ç´ ã¯èªèº«ã®å
é¨ DOM ã shadow tree ã«é ãã¾ãã:
<script>
customElements.define('show-hello', class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `<p>
Hello, ${this.getAttribute('name')}
</p>`;
}
});
</script>
<show-hello name="John"></show-hello>
ããã¯ãçµæã¨ãã¦å¾ããã DOM ã Chrome éçºè ãã¼ã«ã§ã©ã®ããã«è¦ããããã§ãããã¹ã¦ã®ã³ã³ãã³ã㯠â#shadow-rootâ ã®ä¸ã«ããã¾ãã:
æåã«ã elem.attachShadow({mode: â¦}) ãå¼ã³åºããã¨ã§ shadow tree ãä½ããã¾ãã
2ã¤å¶éãããã¾ãã
- è¦ç´ æ¯ã«ä½æã§ãã shadow root ã¯1ã¤ã ãã§ãã
elemã¯ã«ã¹ã¿ã è¦ç´ ããããã¯æ¬¡ã®ããããã§ãªããã°ãªãã¾ããã: âarticleâ, âasideâ, âblockquoteâ, âbodyâ, âdivâ, âfooterâ, âh1â¦h6â, âheaderâ, âmainâ ânavâ, âpâ, âsectionâ, or âspanâã<img>ã®ãããªä»ã®è¦ç´ 㯠shadow tree ãæã¤ãã¨ã¯ã§ãã¾ããã
mode ãªãã·ã§ã³ã¯ã«ãã»ã«åã®ã¬ãã«ãè¨å®ãã¾ããæ¬¡ã®ããããã®å¤ã§ããå¿
è¦ãããã¾ãã:
-
"open"â shadow root ã¯elem.shadowRootã¨ãã¦å©ç¨å¯è½ã§ããä»»æã®ã³ã¼ãã
elemã® shadow tree ã«ã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ãã -
"closed"âelem.shadowRootã¯å¸¸ã«nullã§ãããã®å ´åã¯ã
attachShadowã§è¿å´ãããåç §ã«ãã£ã¦ã®ã¿ shadowDOM ã«ã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ã(ããã¦ãããããããã¯ã¯ã©ã¹å ã«é ããã¦ãã¾ã)ã<input type="range">ãªã©ã®ãã©ã¦ã¶åºæã® shadow tree 㯠closed ã§ãããªã®ã§ããããã«ã¢ã¯ã»ã¹ããæ¹æ³ã¯ããã¾ããã
attachShadow ã§è¿å´ããã shadow root ã¯è¦ç´ ã®ãããªãã®ã§ãinnerHTML ã append ã¨ãã£ã DOM ã¡ã½ããã使ããã¨ãã§ãã¾ãã
shadow root ãæã¤è¦ç´ 㯠âshadow tree hostâ ã¨å¼ã°ããshadow root ã® host ããããã£ã¨ãã¦å©ç¨ã§ãã¾ã:
// {mode: "open"} ã®æ³å®ã§ã, ããã§ãªããã° elem.shadowRoot 㯠null ã§ã
alert(elem.shadowRoot.host === elem); // true
ã«ãã»ã«å
Shadow DOM ã¯ã¡ã¤ã³ã®ããã¥ã¡ã³ãã¨ã¯å¼·ãåºåããã¦ãã¾ã:
- Shadow DOM è¦ç´ 㯠light DOM ããã®
querySelectorã§ã¯è¦ãã¾ãããç¹ã«ãShadow DOM è¦ç´ ã light DOM ã«ãã id ã¨è¡çªãã id ãæã¤å¯è½æ§ãããã¾ãããåé¡ããã¾ãããããã㯠shadow tree å ã§ã®ã¿ä¸æã§ããå¿ è¦ãããã¾ãã - Shadow DOM ã¯ç¬èªã®ã¹ã¿ã¤ã«ã·ã¼ããæã¡ã¾ããå¤é¨ã® DOM ããã®ã¹ã¿ã¤ã«ã«ã¼ã«ã¯é©ç¨ããã¾ããã
ä¾:
<style>
/* ããã¥ã¡ã³ãã®ã¹ã¿ã¤ã«ã¯ #elem å
ã® shadow tree ã«ã¯é©ç¨ããã¾ãã (1) */
p { color: red; }
</style>
<div id="elem"></div>
<script>
elem.attachShadow({mode: 'open'});
// shadow tree ã¯ç¬èªã®ã¹ã¿ã¤ã«ãæã¡ã¾ã (2)
elem.shadowRoot.innerHTML = `
<style> p { font-weight: bold; } </style>
<p>Hello, John!</p>
`;
// <p> 㯠shadow tree å
ã®ã¯ã¨ãªã¼ããã®ã¿è¦ãã¾ã (3)
alert(document.querySelectorAll('p').length); // 0
alert(elem.shadowRoot.querySelectorAll('p').length); // 1
</script>
- ããã¥ã¡ã³ãã®ã¹ã¿ã¤ã«ã¯ shadow tree ã«ã¯å½±é¿ãã¾ããã
- â¦ã§ãããå é¨ã®ã¹ã¿ã¤ã«ã¯æ©è½ãã¾ãã
- shadow tree å ã§è¦ç´ ãåå¾ããã«ã¯ãããªã¼ã®å å´ããã¯ã¨ãªã¼ãè¡ãå¿ è¦ãããã¾ãã
ãªãã¡ã¬ã³ã¹
- DOM: https://dom.spec.whatwg.org/#shadow-trees
- äºææ§: https://caniuse.com/#feat=shadowdomv1
- Shadow DOM ã¯å¤ãã®ä»ã®ä»æ§ã§è¨åããã¦ãã¾ããä¾ãã°ãDOM Parsing ã«ã¯ shadow root ãã
innerHTMLãæã¤ã¨æè¨ããã¦ãã¾ãã
ãµããª
Shadow DOM ã¯ã³ã³ãã¼ãã³ããã¼ã«ã«ãª DOM ã使ããæ¹æ³ã§ãã
shadowRoot = elem.attachShadow({mode: open|closed})âelemã«å¯¾ã㦠shadow DOM ã使ãã¾ããmode="open"ã§ããã°ãelem.shadowRootããããã£ã§ã¢ã¯ã»ã¹å¯è½ã§ããinnerHTMLãä»ã® DOM ã¡ã½ããã使ã£ã¦ãshadowRootã«è¦ç´ ã追å ãããã¨ãã§ãã¾ãã
Shadow DOM è¦ç´ :
- ç¬èªã® id ã¹ã³ã¼ããããã¾ã
- ã¡ã¤ã³ã®ããã¥ã¡ã³ãããã® JavaScript ã»ã¬ã¯ã¿(e.g.
querySelector)ã«ã¯è¦ãã¾ãã - shadow tree å ã®ã¹ã¿ã¤ã«ã®ã¿ã使ç¨ããã¡ã¤ã³ããã¥ã¡ã³ãã®ã¹ã¿ã¤ã«ã¯é©ç¨ããã¾ãã
Shadow DOM ãåå¨ããå ´åããããã âlight DOMâ (é常ã®å)ã®ä»£ããã«ããã©ã¦ã¶ã«ãã£ã¦ã¬ã³ããªã³ã°ããã¾ãããã£ãã¿ã¼ Shadow DOM ã¹ããã, ã³ã³ãã¸ã·ã§ã³ ã§ããããæ§æããæ¹æ³ãè¦ã¦ããã¾ãã
ã³ã¡ã³ã
<code>ã¿ã°ã使ã£ã¦ãã ãããè¤æ°è¡ã®å ´åã¯<pre>ãã10è¡ãè¶ ããå ´åã«ã¯ãµã³ãããã¯ã¹ã使ã£ã¦ãã ãã(plnkr, JSBin, codepenâ¦)ã