HTML <template> ã³ã³ãã³ããã³ãã¬ã¼ãè¦ç´
Baseline
åºãå©ç¨å¯è½
*
ãã®æ©è½ã¯åºãå®è£ ããã¦ãããå¤ãã®ãã¼ã¸ã§ã³ã®ç«¯æ«ããã©ã¦ã¶ã¼ã§åä½ãã¾ãã2015å¹´11æä»¥éããã¹ã¦ã®ãã©ã¦ã¶ã¼ã§å©ç¨å¯è½ã§ãã
* ãã®æ©è½ã®ä¸é¨ã¯ã対å¿ã¬ãã«ãç°ãªãå ´åãããã¾ãã
<template> 㯠HTML ã®è¦ç´ ã§ãHTML ã®ãã©ã°ã¡ã³ããä¿æããå¾ã§ JavaScript ã使ç¨ãã¦ä½¿ç¨ããããã·ã£ã㦠DOM ã®ä¸ã«ç´æ¥çæãããããããã®ã¡ã«ããºã ã¨ãã¦æ©è½ãã¾ãã
屿§
ãã®è¦ç´ ã«ã¯ã°ãã¼ãã«å±æ§ãããã¾ãã
shadowrootmode-
親è¦ç´ ã®ã·ã£ãã¦ã«ã¼ããçæãã¾ãã ããã¯
Element.attachShadow()ã¡ã½ããã®å®£è¨çã§ãåãåæå¤ãåãå ¥ãã¾ããopen-
å é¨ã·ã£ãã¦ã«ã¼ã DOM ã JavaScript ã«å ¬éãã¾ãï¼ã»ã¨ãã©ã®ç¨éã§æ¨å¥¨ï¼ã
closed-
å é¨ã·ã£ãã¦ã«ã¼ã DOM ã JavaScript ããé ãã¾ãã
ã¡ã¢: HTML ãã¼ãµã¼ã¯ããã®å±æ§ãè¨å®ããã¦ãããã¼ãã®æåã®
<template>ã«å¯¾ãã¦ãDOM ã«ShadowRootãªãã¸ã§ã¯ãã使ãã¾ãã ãã®å±æ§ãè¨å®ããã¦ããªãå ´åãã¾ãã¯è¨±å¯ãããå¤ãè¨å®ããã¦ããªãå ´åããããã¯ShadowRootãæ¢ã«åã親ã«å®£è¨çã«ä½æããã¦ããå ´åã¯ãHTMLTemplateElementã使ããã¾ããHTMLTemplateElementã¯ãHTMLTemplateElement.shadowRootModeãè¨å®ããããããã¨ã§ãè§£éå¾ã«ã·ã£ãã¦ã«ã¼ãã«å¤æ´ãããã¨ã¯ã§ãã¾ãããã¡ã¢: å¤ããã¥ã¼ããªã¢ã«ãä¾ã§ã¯ãChrome 90-110 ã§å¯¾å¿ãã¦ãã鿍æºã®
shadowroot屿§ãè¦ã¤ããããããã¾ããããã®å±æ§ã¯åé¤ãããæ¨æºã®shadowrootmode屿§ã«ç½®ãæãããã¦ãã¾ãã shadowrootclonable-
ãã®è¦ç´ ã使ç¨ãã¦ä½æãã
ShadowRootã®clonableããããã£ã®å¤ãtrueã«è¨å®ãã¾ãã è¨å®ããã¦ããå ´åãã·ã£ãã¦ãã¹ãï¼ãã®<template>ã®è¦ªè¦ç´ ï¼ã®è¤è£½ãNode.cloneNode()ã¾ãã¯Document.importNode()ã§ä½æããã¨ãã³ãã¼ã«ã·ã£ãã¦ã«ã¼ããå«ã¾ãã¾ãã shadowrootcustomelementregistry-
ãã®è¦ç´ ã使ç¨ãã¦ä½æããã
ShadowRootã®customElementRegistryããããã£ããææ¸ã® ã«ã¹ã¿ã è¦ç´ ã¬ã¸ã¹ããªã¼ ã§ã¯ãªããnullã«è¨å®ãã¾ãã ããã«ãããã¹ã³ã¼ãåãããCustomElementRegistryããå¾ããCustomElementRegistry.initialize()ã使ç¨ãã¦æ·»ä»ã§ãã¾ãã shadowrootdelegatesfocus-
ãã®è¦ç´ ã使ç¨ãã¦ä½æãã
ShadowRootã®delegatesFocusããããã£ã®å¤ãtrueã«è¨å®ãã¾ãã ãããè¨å®ããã¦ãã¦ãã·ã£ãã¦ããªã¼å ã®ãã©ã¼ã«ã¹å¯è½ã§ãªãè¦ç´ ã鏿ããã¦ããå ´åããã©ã¼ã«ã¹ã¯ããªã¼å ã®æåã®ãã©ã¼ã«ã¹å¯è½ãªè¦ç´ ã«è²ããã¾ãã ãã®å¤ã¯falseãæ¢å®å¤ã§ãã shadowrootreferencetarget-
ãã®è¦ç´ ã使ç¨ãã¦çæããã
ShadowRootã®referenceTargetããããã£ã®å¤ãè¨å®ãã¾ããå¤ã¯ã·ã£ã㦠DOM å ã®è¦ç´ ã® ID ã§ããå¿ è¦ãããã¾ããè¨å®ããã¨ãã·ã£ã㦠DOM å¤ãããã¹ãè¦ç´ ã¸ã®åç §ãè¡ãããå ´åãåç §ããã対象è¦ç´ ããã¹ãè¦ç´ ã¸ã®åç §ã®æå¹ãªã¿ã¼ã²ããã¨ãªãã¾ãã shadowrootserializable-
ãã®è¦ç´ ã使ç¨ãã¦ä½æãã
ShadowRootã®serializableããããã£ã®å¤ãtrueã«è¨å®ãã¾ãã è¨å®ããã¦ããå ´åãã·ã£ãã¦ã«ã¼ãã¯Element.getHTML()ã¾ãã¯ShadowRoot.getHTML()ã¡ã½ããããoptions.serializableShadowRoots弿°ãtrueã«è¨å®ãã¦å¼ã³åºããã¨ã§ã·ãªã¢ã©ã¤ãºããã¾ãã ãã®å¤ã¯falseãæ¢å®å¤ã§ãã shadowrootslotassignment-
ãã®è¦ç´ ã使ç¨ãã¦ä½æããã
ShadowRootã®slotAssignmentããããã£ãè¨å®ãã¾ãã ããã¯Element.attachShadow()ã¡ã½ããã®slotAssignmentãªãã·ã§ã³ã®å®£è¨çãªåçç©ã§ããnamed-
ãã®ã·ã£ãã¦ã«ã¼ãå ã®
<slot>è¦ç´ ã«ã¯ãèªåçã«è¦ç´ ãå²ãå½ã¦ããã¾ãã ãããããã©ã«ãå¤ã§ããslot屿§ãæã¤è¦ç´ ã¯ããã³ãã¬ã¼ãå ã§å¯¾å¿ããname屿§ãæã¤æåã®<slot>ã«å²ãå½ã¦ããã¾ãã è¤æ°ã®è¦ç´ ã§åãã¹ãããåãæå®ããã¦ããå ´åããããã¯ãã¹ã¦ããã³ãã¬ã¼ãå ã§ãã®ååãæã¤æåã®ã¹ãããã«è¿½å ããã宣è¨ãããé åºã§ã¬ã³ããªã³ã°ããã¾ãã ååãæå®ããã¦ããªãè¦ç´ ï¼slot屿§ãæå®ãã¦ããªãè¦ç´ ï¼ã¯ãã¹ã¦ã宣è¨ãããé åºã§ããã©ã«ãã®ã¹ãããã«ä»£å ¥ããã¾ãã ããã¯ããã³ãã¬ã¼ãå ã®æåã®ååãæå®ããã¦ããªã<slot>ã§ãã manual-
è¦ç´ ã¯ç¹å®ã® slot è¦ç´ ã«ã
HTMLSlotElement.assign()ã使ç¨ãã¦æåã§å²ãå½ã¦ããã¾ãã èªåçãªå²ãå½ã¦ã¯è¡ããã¾ããã
使ç¨ä¸ã®ã¡ã¢
ãã®è¦ç´ ã«ã¯ã許å¯ããã¦ããã³ã³ãã³ãã¯ããã¾ãããä¸ã«å«ã¾ãã HTML ã½ã¼ã¹ã¯ãå®éã«ã¯ <template> è¦ç´ ã®åã«ãªãããã§ã¯ãªãããã§ãã <template> è¦ç´ ã® Node.childNodes ããããã£ã¯å¸¸ã«ç©ºã§ãããå
å´ã®ã³ã³ãã³ãã®ããã«è¦ãããã®ã«ã¢ã¯ã»ã¹ããã«ã¯ãç¹æ®ãª content ããããã£ã使ç¨ãã¾ããNode.appendChild() ã¾ãã¯åæ§ã®ã¡ã½ããã <template> è¦ç´ ã«å¯¾ãã¦å¼ã³åºãã¨ããã® <template> è¦ç´ èªèº«ã®åãæ¿å
¥ãããã¨ã«ãªããã³ã³ãã³ãã¢ãã«éåã¨ãªãä¸ãå®éã«ã¯ content ããããã£ããè¿ããã DocumentFragment ãæ´æ°ããã¾ããã
<template> è¦ç´ ã®æ§æè§£æã®ä»çµã¿ä¸ããã³ãã¬ã¼ãå
ã® <html>ã<head>ã<body> ã®éå§ã¿ã°ããã³çµäºã¿ã°ã¯ããã¹ã¦ãã¼ãµã¼ããæ§æã¨ã©ã¼ã¨ãã¦ç¡è¦ããã¾ãããããã£ã¦ã<template><head><title>Test</title></head></template> 㯠<template><title>Test</title></template> ã¨åçã§ãã
<template> è¦ç´ ã®ç¨éã¯ä¸»ã« 2 ã¤ããã¾ãã
ãã³ãã¬ã¼ãææ¸ãã©ã°ã¡ã³ã
æ¢å®ã§ã¯ãè¦ç´ ã®ã³ã³ãã³ãã¯ã¬ã³ããªã³ã°ããã¾ããã
対å¿ãã HTMLTemplateElement ã¤ã³ã¿ã¼ãã§ã¤ã¹ã¯ãæ¨æºã§ content ããããã£ãå«ã¿ã¾ãï¼åçã® content/markup 屿§ã¯ããã¾ããï¼ããã® content ããããã£ã¯èªã¿åãå°ç¨ã§ããã³ãã¬ã¼ãã表ã DOM ãµãããªã¼ãæ ¼ç´ãã DocumentFragment ãä¿æãã¾ãã
Node.cloneNode() ã¡ã½ãã㨠Document.importNode() ã¡ã½ããã¯ã©ã¡ãããã¼ãã®ã³ãã¼ãçæãã¾ããéãã¯ãimportNode() ãå¼ã³åºãå
ã®ææ¸ã®ã³ã³ããã¹ãã§ãã¼ããè¤è£½ããã®ã«å¯¾ããcloneNode() ã¯è¤è£½å¯¾è±¡ã®ãã¼ããå±ããææ¸ã使ç¨ããç¹ã§ããææ¸ã³ã³ããã¹ãã¯ãã«ã¹ã¿ã è¦ç´ ãæ§ç¯ããããã® CustomElementRegistry ãæ±ºå®ãã¾ãããã®ãããcontent ãã©ã°ã¡ã³ããè¤è£½ããé㯠document.importNode() ã使ç¨ããã«ã¹ã¿ã è¦ç´ ã®åå«ããã³ãã¬ã¼ãã³ã³ãã³ããææãã奿æ¸ã§ã¯ãªããç¾å¨ã®ææ¸å
ã®å®ç¾©ã使ç¨ãã¦æ§ç¯ãããããã«ãã¾ãã詳細㯠Node.cloneNode() ãã¼ã¸ã®ä¾ãåç
§ãã¦ãã ããã
DocumentFragment ã³ã³ããã¼ãã®ãã®ã«ã¯ãã¼ã¿ãæ·»ä»ããªãããã«æ³¨æãã¦ãã ããã詳細㯠DocumentFragment ã®ãã¼ã¿ã¯ã¯ãã¼ã³ãããªãã®ä¾ãåç
§ãã¦ãã ããã
宣è¨çã·ã£ã㦠DOM
ãã <template> è¦ç´ ã shadowrootmode 屿§ã®å¤ open ã¾ã㯠closed ãæ ¼ç´ããã¨ãHTML ãã¼ãµã¼ã¯ç´ã¡ã«ã·ã£ã㦠DOM ãçæãã¾ãããã®è¦ç´ 㯠ShadowRoot ã§ã©ãããããã³ã³ãã³ãã«ãã£ã¦ DOM å
ã§ç½®ãæãããã親è¦ç´ ã«è£
çããã¾ãã
ãã㯠Element.attachShadow() ãå¼ã³åºãã¦è¦ç´ ã«ã·ã£ãã¦ã«ã¼ããä»ããã®ã¨å®£è¨çã«ç価ã§ãã
è¦ç´ ã shadowrootmode ã«ä»ã®å¤ã示ãå ´åãã¾ã㯠shadowrootmode 屿§ãæããªãå ´åããã¼ãµã¼ã¯ HTMLTemplateElement ãçæãã¾ãã
åæ§ã«ã宣è¨çã·ã£ãã¦ã«ã¼ããè¤æ°ããå ´åãæåã®ã·ã£ãã¦ã«ã¼ãã®ã¿ã ShadowRoot ã§ç½®ãæãããããã以é㯠HTMLTemplateElement ãªãã¸ã§ã¯ãã¨ãã¦è§£éã§ãã¾ãã
shadowroot ã¨ããæ¥é è¾ã®ä»ãããã®ä»ã®å±æ§ã使ç¨ããã¨ãã¹ãããã®å²ãå½ã¦æ¹æ³ãå¶å¾¡ãããªã©ãShadowRoot ã宣è¨çã«ã«ã¹ã¿ãã¤ãºãããã¨ãã§ãã¾ãã
ä¾
>表ã®è¡ãçæ
ã¾ããHTML é¨åã®ä¾ããå§ãã¾ãããã
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- æ¢åã®ãã¼ã¿ã¯ãå¿
è¦ã«å¿ãã¦ããã«å«ãããã¨ãã§ãã¾ã -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
ã¾ããJavaScript ã³ã¼ãã使ç¨ãã¦å¾ããã³ã³ãã³ããæ¿å ¥ããããã®è¡¨ãä½ãã¾ããæ¬¡ã«ã1 è¡åã表ã HTML æçã®æ§é ãæ¸ããããã³ãã¬ã¼ããç¶ãã¾ãã
表ãçæããããã³ãã¬ã¼ããå®ç¾©ããã¾ããã JavaScript ã使ã£ã¦ããã³ãã¬ã¼ããåºã«æ§ç¯ãããåè¡ãè¡¨ã«æ¿å ¥ãã¾ãã
// template è¦ç´ ã® content 屿§ã®æç¡ã確èªãããã¨ã§ã
// ãã©ã¦ã¶ã¼ã HTML ã® template è¦ç´ ã«å¯¾å¿ãã¦ããããã¹ããã¾ãã
if ("content" in document.createElement("template")) {
// æ¢åã® HTML tbody 㨠template ã®è¡ã使ã£ã¦
// table ãã¤ã³ã¹ã¿ã³ã¹çæãã¾ãã
const tbody = document.querySelector("tbody");
const template = document.querySelector("#productrow");
// æ°ããè¡ãè¤è£½ãã¦è¡¨ã«æ¿å
¥ãã¾ãã
const clone = template.content.cloneNode(true);
let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// æ°ããè¡ãè¤è£½ãã¦è¡¨ã«æ¿å
¥ãã¾ãã
const clone2 = template.content.cloneNode(true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// HTML ã® template è¦ç´ ã«å¯¾å¿ãã¦ããªãã®ã§
// 表ã«è¡ã追å ããã»ãã®æ¹æ³ãæ¢ãã¾ãã
}
çµæã¨ãã¦ã JavaScript ãéãã¦ãæ°ããè¡ã追å ããã HTML ã®è¡¨ãã§ãã¾ãã
宣è¨çã·ã£ã㦠DOM ã®å®è£
ãã®ä¾ã§ã¯ããã¼ã¯ã¢ããã®å§ãã«é表示ã§å¯¾å¿ããè¦åãè¨è¼ãã¦ãã¾ãããã®è¦åã¯å¾ã§ãã©ã¦ã¶ã¼ã® shadowrootmode 屿§ã«å¯¾å¿ãã¦ããªãå ´åã« JavaScript ã§è¡¨ç¤ºããããã«è¨å®ãã¾ããæ¬¡ã®è¨äºã«ã¯ 2 ã¤ã® <article> è¦ç´ ããããããããç°ãªãæ¯ãèãããã <style> è¦ç´ ãå«ãã§ãã¾ããæåã® <style> è¦ç´ ã¯ææ¸å
¨ä½ã«å¯¾ãã¦ã°ãã¼ãã«ã§ãã2 ã¤ç®ã¯ shadowrootmode 屿§ãåå¨ããããã<template> è¦ç´ ã®ä»£ããã«çæãããã·ã£ãã¦ã«ã¼ãã«ã¹ã³ã¼ãããã¾ãã
<p hidden>
â ãã®ãã©ã¦ã¶ã¼ã¯ã¾ã <code>shadowrootmode</code> 屿§ã«å¯¾å¿ãã¦ãã¾ããã
</p>
<article>
<style>
p {
padding: 8px;
background-color: wheat;
}
</style>
<p>I'm in the DOM.</p>
</article>
<article>
<template shadowrootmode="open">
<style>
p {
padding: 8px;
background-color: plum;
}
</style>
<p>I'm in the shadow DOM.</p>
</template>
</article>
const isShadowRootModeSupported = Object.hasOwn(
HTMLTemplateElement.prototype,
"shadowRootMode",
);
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootModeSupported);
ãã©ã¼ã«ã¹ãè²æ¸¡ãä¼´ã宣è¨çã·ã£ã㦠DOM
ãã®ä¾ã§ã¯ãshadowrootdelegatesfocus ã宣è¨çã«ä½æããã·ã£ãã¦ã«ã¼ãã«é©ç¨ãããã©ã¼ã«ã¹ã«ã©ã®ãããªå¹æããããã示ãã¾ãã
ãã®ã³ã¼ãã§ã¯ãæåã« <template> è¦ç´ ã« shadowrootmode 屿§ãç¨ãã¦ã<div> è¦ç´ ã®ä¸ã«ã·ã£ãã¦ã«ã¼ãã宣è¨ãã¾ãã
ããã«ãããããã¹ããæ ¼ç´ãããã©ã¼ã«ã¹ã§ããªã <div> ã¨ããã©ã¼ã«ã¹ã§ãã <input> è¦ç´ ã®ä¸¡æ¹ã表示ããã¾ãã
ã¾ãã:focus ãæã¤è¦ç´ ãéã«ã¹ã¿ã¤ã«è¨å®ãããã¹ãè¦ç´ ã®é常ã®ã¹ã¿ã¤ã«è¨å®ãè¨å®ããã«ã¯ CSS ã使ç¨ãã¾ãã
<div>
<template shadowrootmode="open">
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>ã¯ãªãã¯å¯è½ãªã·ã£ã㦠DOM ããã¹ã</div>
<input type="text" placeholder="ã·ã£ã㦠DOM å
ã®å
¥å" />
</template>
</div>
2 ã¤ç®ã®ã³ã¼ããããã¯ã¯ãshadowrootdelegatesfocus 屿§ãè¨å®ãã¦ãã以å¤ã¯åãã§ãããã®å±æ§ã¯ãããªã¼å
ã®ãã©ã¼ã«ã¹å¯è½ã§ãªãè¦ç´ ã鏿ãããå ´åã«ãããªã¼å
ã®æåã®ãã©ã¼ã«ã¹å¯è½ãªè¦ç´ ã«ãã©ã¼ã«ã¹ãè²ããã®ã§ãã
<div>
<template shadowrootmode="open" shadowrootdelegatesfocus>
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>ã¯ãªãã¯å¯è½ãªã·ã£ã㦠DOM ããã¹ã</div>
<input type="text" placeholder="ã·ã£ã㦠DOM å
ã®å
¥å" />
</template>
</div>
æå¾ã«ã以ä¸ã® CSS ã使ç¨ãã¦ã親è¦ç´ ã§ãã <div> ã«ãã©ã¼ã«ã¹ãããã¨ãã«èµ¤ã®æ ç·ãé©ç¨ãã¾ãã
div:focus {
border: 2px solid red;
}
ãã®çµæãä¸è¨ã«ç¤ºãã¾ãã
HTML ã¯æåã«ã¬ã³ããªã³ã°ãããã¨ããæåã®ç»åã«ç¤ºãããã«è¦ç´ ã«ã¯ã¹ã¿ã¤ã«è¨å®ãããã¾ããã
shadowrootdelegatesfocus ãè¨å®ããã¦ããªãã·ã£ãã¦ã«ã¼ãã§ã¯ã<input> 以å¤ã®å ´æãã¯ãªãã¯ãã¦ããã©ã¼ã«ã¹ã¯å¤ããã¾ããï¼<input> è¦ç´ ã鏿ãã㨠2 ã¤ç®ã®ç»åã®ããã«ãªãã¾ãï¼ã

shadowrootdelegatesfocus ãè¨å®ããã·ã£ãã¦ã«ã¼ãã§ã¯ãããã¹ãï¼ãã©ã¼ã«ã¹ã§ããªãï¼ãã¯ãªãã¯ããã¨ã<input> è¦ç´ ã鏿ããã¾ãã
ããã¯ä¸è¨ã«ç¤ºãããã«è¦ªè¦ç´ ããã©ã¼ã«ã¹ããã¾ãã

ååä»ãã¹ãããå²ãå½ã¦ãè¡ã宣è¨çãªã·ã£ã㦠DOM
ãã®ä¾ã§ã¯ãè¦ç´ ã® slot 屿§ã«åºã¥ãã¦ï¼ã¹ãããã® name 屿§ã¨ç
§åãããã¨ã§ï¼ãã·ã£ã㦠DOM å
ã®ã¹ãããã«è¦ç´ ã代å
¥ããæ¹æ³ã示ãã¦ãã¾ãã
HTML
ã¾ããã¿ã¤ãã«ãã¡ã¿ãã¼ã¿ãããã³è¨äºæ¬æã®æ
å ±ã表示ãã <article> è¦ç´ ãå®ç¾©ãã¾ãã
ãã®è¨äºã«ã¯ <template> è¦ç´ ãå«ã¾ãã¦ãããshadowrootmode 屿§ãè¨å®ããã¦ãããããã·ã£ãã¦ã«ã¼ãã¨ãªãã¾ãã
ååä»ãã¹ãããã®å²ãå½ã¦ãããã©ã«ãã§ãããããshadowrootslotassignment 屿§ãè¨å®ããå¿
è¦ã¯ããã¾ããã
ãã®ãã³ãã¬ã¼ãã§ã¯ã"header" ããã³ "meta" æ å ±ç¨ã®ååä»ãã¹ãããã¨ã"body" æ å ±ç¨ã®ååãªãã¹ããããæã¤è¦ç´ ãå®ç¾©ãã¦ãã¾ãã åè¦ç´ ã«ã¯ç°ãªãã¹ã¿ã¤ã«è¨å®ãé©ç¨ããã¦ãããåºå¥ãããããªã£ã¦ãã¾ãã
<article id="host">
<template shadowrootmode="open" shadowrootslotassignment="named">
<style>
.header {
background-color: plum;
}
.meta {
background-color: green;
}
.body {
background-color: lightblue;
}
</style>
<h2 class="header">
<slot name="title"></slot>
</h2>
<div class="meta">
<slot name="meta"></slot>
</div>
<div class="body">
<slot></slot>
</div>
</template>
<p>
ã¹ããã屿§ãã¤ãã¦ããªãããã¹ã 1 ã§ãã"body" ã® div å
ã®ããã©ã«ãï¼ååãªãï¼ã®ã¹ãããã«é
ç½®ããã¾ãã
</p>
<span slot="title">title ã¹ãããã®ããã¹ã</span>
<span slot="meta">meta ã¹ãããã®ããã¹ã</span>
<p>
ã¹ããã屿§ãã¤ãã¦ããªãããã¹ã 2 ã§ããåæã«ã"body" ã® div å
ã®ããã©ã«ãï¼ååãªãï¼ã®ã¹ãããã«ãé
ç½®ããã¾ãã
</p>
</article>
åããã¹ãå
ã®ããã³ãã¬ã¼ãã®ä¸ã«ãã¹ãããã«ãã¼ã¿ãè¨å®ããããã® 4 ã¤ã®è¦ç´ ãæå®ããã¦ãã¾ãã
<span> è¦ç´ ã«ã¯ããã³ãã¬ã¼ãå
ã®ã¹ãããã® name 屿§ã¨ä¸è´ãã slot 屿§ãããã対å¿ããã¹ãããã«ãã¼ã¿ãè¨å®ããã¾ãã
2ã¤ã®<p>è¦ç´ ã«ã¯ååãæå®ããã¦ããªããããã©ã¡ãã "body" è¦ç´ å
ã®ååãæå®ããã¦ããªã <slot> ã«æ¿å
¥ããã¾ãã
çµæ
ä¸ã®ä¾ã§ã¯ãåã»ã¯ã·ã§ã³ã«ã¹ãããã®ã³ã³ãã³ãã表示ããã¦ããã¯ãã§ãã
æåã§ã¹ããããä»£å ¥ãã宣è¨åã·ã£ã㦠DOM
ãã®ä¾ã§ã¯ãæåã«ããã¹ãããå²ãå½ã¦ã使ç¨ãã¦ãã·ã£ã㦠DOM å ã®ã¹ãããã«è¦ç´ ãå²ãå½ã¦ãææ³ã«ã¤ãã¦èª¬æãã¾ãã
ãã®ææ³ã§ã¯ãããããã®è¦ç´ ãå ·ä½çãªã¹ãããã«æåã§å²ãå½ã¦ãå¿ è¦ãããã¾ãã ããã©ã«ãã®å²ãå½ã¦ã¯ãªããããå²ãå½ã¦ããã¦ããªãã¹ãããã¯ç©ºã«ãªãã¾ãã
HTML
ã¾ããé表示ã®å¯¾å¿ã«é¢ããè¦åãããã¾ãã
ãã®è¦åã¯ããã©ã¦ã¶ã¼ã shadowrootslotassignment 屿§ã対å¿ãã¦ããªãå ´åãå¾ã§ JavaScript ã§è¡¨ç¤ºãããããã«è¨å®ããã¦ãã¾ãã
<p id="support-warning" hidden>
â ãã®ãã©ã¦ã¶ã¼ã¯ãã¾ã <code>shadowrootslotassignment</code> 屿§ã«å¯¾å¿ãã¦ãã¾ããã
</p>
次ã«ãã¿ã¤ãã«ãã¡ã¿ãã¼ã¿ãããã³è¨äºæ¬æã®æ
å ±ã表示ãã <article> è¦ç´ ãå®ç¾©ãã¾ãã
ããã«ã¯ <template> è¦ç´ ãå«ã¾ãã¦ãããshadowrootmode 屿§ãè¨å®ããã¦ããããã·ã£ãã¦ã«ã¼ãã¨ãªããshadowrootslotassignment="manual" ãè¨å®ããã¦ãããããã¹ãããã®æåå²ãå½ã¦ã使ç¨ããã¾ãã
ãã®ãã³ãã¬ã¼ãã§ã¯ã"header"ã"meta"ã"body" æ
å ±ã®ã¹ããããæã¤è¦ç´ ãå®ç¾©ããã¦ãããããããã® id 屿§ã«ãã£ã¦å¥åã«åç
§ãããã¨ãã§ãã¾ãã
åè¦ç´ ã«ã¯ç°ãªãã¹ã¿ã¤ã«è¨å®ãé©ç¨ããã¦ãããããåºå¥ã容æã§ãã
<article id="host">
<template shadowrootmode="open" shadowrootslotassignment="manual">
<style>
.header {
background-color: plum;
}
.meta {
background-color: green;
}
.body {
background-color: lightblue;
}
</style>
<h2 class="header">
<slot id="titleSlot"></slot>
</h2>
<div class="meta">
<slot id="metaSlot"></slot>
</div>
<div class="body">
<slot id="bodySlot"></slot>
</div>
</template>
<span id="text_title">title ã¹ãããã®ããã¹ã</span>
<span id="text_meta">meta ã¹ãããã®ããã¹ã</span>
<p id="text_body_1">body ã¹ãããã®ããã¹ã 1 ã§ãã</p>
<p id="text_body_2">body ã¹ãããã®ããã¹ã 2 ã§ãã</p>
</article>
åããã¹ãå ã®ãã³ãã¬ã¼ãã®ä¸è¨ã«ã¯ãã¹ãããã«ãã¼ã¿ãå ¥åããããã® 4 ã¤ã®è¦ç´ ãæå®ããã¦ãã¾ãã ãããã ID ã§èå¥ããã¾ãã
JavaScript
æåã§ã®ã¹ãããå²ãå½ã¦ãè¡ã JavaScript ã¯ãä¸è¨ã«ç¤ºãéãã§ãã
ã¾ããã³ã¼ãã¯ã·ã£ãã¦ã«ã¼ãå
ã®ã¹ããããåå¾ããæ¬¡ã«æ¿å
¥ããããã¹ããåå¾ããæå¾ã«ãã®ããã¹ããã¹ãããã«å²ãå½ã¦ã¾ãã
ãªããç¹å®ã®ã¹ãããã«ã¯ãã¼ãã 1 åããå²ãå½ã¦ããã¨ãã§ãã¾ãããã¾ããHTMLSlotElement.assign() ã使ç¨ãã¦åä¸ã®ã¹ãããã«è¤æ°ã®ãã¼ããå²ãå½ã¦ãå ´åãæå®ãããé åºã追å ãããé åºã決å®ãã¾ãã
const host = document.querySelector("#host");
const shadow = host.shadowRoot;
// 1. ã¹ãããã対象ã¨ãã
const titleSlot = shadow.querySelector("#titleSlot");
const metaSlot = shadow.querySelector("#metaSlot");
const bodySlot = shadow.querySelector("#bodySlot");
// 2. ã¹ãããã«å
¥ããè¦ç´ ã対象ã¨ãã
const body1Text = document.querySelector("#text_body_1");
const body2Text = document.querySelector("#text_body_2");
const titleText = document.querySelector("#text_title");
const metaText = document.querySelector("#text_meta");
// 3. æåã§å²ãå½ã¦ã
titleSlot.assign(titleText);
metaSlot.assign(metaText);
bodySlot.assign(body2Text, body1Text);
ã¹ãããã®å²ãå½ã¦ã«å¯¾å¿ãã¦ããªãå ´åããã®ã³ã¼ãã¯é表示ã®å¯¾å¿è¦åã表示ããã¾ãã
const isShadowRootSlotAssignmentSupported = Object.hasOwn(
HTMLTemplateElement.prototype,
"shadowRootSlotAssignment",
);
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootSlotAssignmentSupported);
çµæ
ä¸ã®ä¾ã§ã¯ãåã»ã¯ã·ã§ã³ã«ã¹ãããã®ã³ã³ãã³ãã表示ããã¦ããã¯ãã§ãã
ã¡ã¢:
shadowrootslotassignment 屿§ã対å¿ãã¦ããªãå ´åãè¦åã¡ãã»ã¼ã¸ã表示ããããã©ã¦ã¶ã¼ã¯ named ã®å²ãå½ã¦ã使ç¨ãã¾ãã
ãã ããæ¿å
¥ãããã¹ããããè¦ç´ ã®ããããååãä»ãããã¦ããªãããããã¹ã¦ã®è¦ç´ ãã¿ã¤ãã«ã¹ãããã«æ¿å
¥ããã¾ãï¼ããã¯ããããæåã®ç¡åã®ã¹ãããã§ããããããã£ã¦ãããã©ã«ããã®ã¹ãããã¨ãªãããã§ãï¼ã
DocumentFragment ã®ãã¼ã¿ã¯ã¯ãã¼ã³ãããªã
DocumentFragment ã®å¤ã渡ãããã¨ãNode.appendChild ãåæ§ã®ã¡ã½ããã¯ãã®å¤ã®åãã¼ãã ãã対象ã¨ãããã¼ãã«ç§»åããã¾ãããããã£ã¦ãã¤ãã³ããã³ãã©ã¼ã¯ DocumentFragment èªä½ã§ã¯ãªããDocumentFragment ã®åãã¼ãã«è¨å®ãããã¨ãæ¨å¥¨ããã¾ãã
以ä¸ã® HTML ããã³ JavaScript ãèãã¦ã¿ã¦ãã ããã
HTML
<div id="container"></div>
<template id="template">
<div>ã¯ãªãã¯ãã¦ãã ãã</div>
</template>
JavaScript
const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
event.target.append(" â ãã® div ãã¯ãªãã¯ããã¾ãã");
}
const firstClone = document.importNode(template.content, true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
const secondClone = document.importNode(template.content, true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
çµæ
firstClone 㯠DocumentFragment ãªã®ã§ãappendChild ãå¼ã³åºãããã¨ãã« container ã«è¿½å ãããã®ã¯ãã®åãã¼ãã ãã§ãfirstClone ã®ã¤ãã³ããã³ãã©ã¼ã¯ã³ãã¼ããã¾ããã䏿¹ãsecondClone ã¯æåã®åãã¼ãã«ã¤ãã³ããã³ãã©ã¼ã追å ããã¦ãããããappendChild ãå¼ã³åºãããã¨ã¤ãã³ããã³ãã©ã¼ãã³ãã¼ãããã¯ãªãã¯ããã¨æå¾
éãã«åä½ãã¾ãã
æè¡çæ¦è¦
| ã³ã³ãã³ãã«ãã´ãªã¼ | ã¡ã¿ãã¼ã¿ã³ã³ãã³ã, ããã¼ã³ã³ãã³ã, è¨è¿°ã³ã³ãã³ã, ã¹ã¯ãªãã対å¿è¦ç´ |
|---|---|
| 許å¯ããã¦ããå 容 | ãªãï¼ä½¿ç¨ä¸ã®ã¡ã¢ãåç §ï¼ |
| ã¿ã°ã®çç¥ | ãªããéå§ã¿ã°ã¨çµäºã¿ã°ã®ä¸¡æ¹ãå¿ é ã§ãã |
| 許å¯ããã¦ãã親è¦ç´ |
ã¡ã¿ãã¼ã¿ã³ã³ãã³ã,
è¨è¿°ã³ã³ãã³ã,
ã¹ã¯ãªãã対å¿è¦ç´ ãåãä»ãããã¹ã¦ã®è¦ç´ ã
ã¾ããspan 屿§ãæããªã <colgroup> è¦ç´ ã®åã«ãªããã¨ãã§ãã¾ãã
|
| æé»ã® ARIA ãã¼ã« | 対å¿ãããã¼ã«ãªã |
| 許å¯ããã¦ãã ARIA ãã¼ã« | 許å¯ããã¦ãã role ãªã |
| DOM ã¤ã³ã¿ã¼ãã§ã¤ã¹ | HTMLTemplateElement |
仿§æ¸
| 仿§æ¸ |
|---|
| HTML > # the-template-element > |
ãã©ã¦ã¶ã¼ã®äºææ§
é¢é£æ å ±
partããã³exportparts屿§<slot>è¦ç´:hostã:host()ã:host-context()æ¬ä¼¼ã¯ã©ã¹::partã::slottedæ¬ä¼¼è¦ç´ShadowRootã¤ã³ã¿ã¼ãã§ã¤ã¹- ãã³ãã¬ã¼ãã¨ã¹ãããã®ä½¿ç¨
- CSS ã¹ã³ã¼ãåã¢ã¸ã¥ã¼ã«
- 宣è¨çã·ã£ã㦠DOM ï¼HTML ã«ããï¼ ï¼ã·ã£ã㦠DOM ã®ä½¿ç¨ï¼
- Declarative shadow DOM (web.dev, 2023)