Attributen
Dit element bevat de globale attributen.
|
Creëert een shadow root voor het bovenliggende element.
Dit is een declaratieve versie van de methode
Opmerking
De HTML-parser maakt een Opmerking
U kunt het niet-standaard attribuut | |
Stelt de waarde in van de eigenschap clonable van een ShadowRoot die met dit element wordt gemaakt, op true.
Indien ingesteld, zal een kloon van de shadow host (het bovenliggende element van dit <template>) die is gemaakt met Node.cloneNode() of Document.importNode(), een shadow root in de kopie bevatten. | |
Stelt de eigenschap customElementRegistry in van een ShadowRoot die met dit element wordt gemaakt, op null, in plaats van op het custom-element-register van het document.
Hierdoor kan later een scoped CustomElementRegistry worden gekoppeld met CustomElementRegistry.initialize(). | |
Stelt de waarde in van de eigenschap delegatesFocus van een ShadowRoot die met dit element wordt gemaakt, op true.
Als dit is ingesteld en een niet-focusbaar element in de shadow tree wordt geselecteerd, dan wordt de focus gedelegeerd aan het eerste focusbare element in de tree.
De standaardwaarde is false. | |
| Stelt de waarde in van de eigenschap referenceTarget van een ShadowRoot die met dit element wordt gemaakt. De waarde moet het ID zijn van een element binnen de shadow DOM. Indien ingesteld, zorgen doelverwijzingen naar het hostelement van buiten de shadow DOM ervoor dat het aangewezen doelelement het effectieve doel wordt van de verwijzing naar het hostelement. |
Stelt de waarde in van de eigenschap serializable van een ShadowRoot die met dit element wordt gemaakt, op true.
Indien ingesteld, kan de shadow root worden geserialiseerd door de methoden Element.getHTML() of ShadowRoot.getHTML() aan te roepen met de parameter options.serializableShadowRoots ingesteld op true.
De standaardwaarde is false. | |
| Stelt de eigenschap slotAssignment in van een ShadowRoot die met dit element wordt gemaakt.
Dit is het declaratieve equivalent van de optie slotAssignment van de methode Element.attachShadow().
|
Gebruiksaanwijzingen
Dit element heeft geen toegestane inhoud, omdat alles wat erin genest is in de HTML-broncode niet daadwerkelijk de kinderen wordt van het <template>-element. De eigenschap Node.childNodes van het <template>-element is altijd leeg, en u kunt de geneste inhoud alleen benaderen via de speciale eigenschap content. Als u echter Node.appendChild() of vergelijkbare methoden aanroept op het <template>-element, dan voegt u kinderen toe aan het <template>-element zelf, wat een schending is van het bijbehorende inhoudsmodel en niet daadwerkelijk de DocumentFragment bijwerkt die door de content-eigenschap wordt geretourneerd.
Vanwege de manier waarop het <template>-element wordt geparsed, zijn alle openings- en sluitingstags van <html>, <head> en <body> binnen de template syntaxisfouten en worden ze door de parser genegeerd, dus <template><head><title>Test</title></head></template> is hetzelfde als <template><title>Test</title></template>.
Er zijn twee belangrijke manieren om het <template>-element te gebruiken.
Documentfragment als template
Standaard wordt de inhoud van het element niet weergegeven.
De bijbehorende HTMLTemplateElement-interface bevat een standaardeigenschap content (zonder equivalent inhouds-/opmaakattribuut). Deze content-eigenschap is alleen-lezen en bevat een DocumentFragment met de DOM-subboom die door de template wordt vertegenwoordigd.
De methoden Node.cloneNode() en Document.importNode() maken beide een kopie van een node. Het verschil is dat importNode() de node kloont in de context van het aanroepende document, terwijl cloneNode() het document gebruikt van de node die wordt gekloond. De documentcontext bepaalt het CustomElementRegistry voor het construeren van eventuele custom elements. Gebruik daarom document.importNode() om het content-fragment te klonen, zodat afstammelingen die custom elements zijn worden geconstrueerd met de definities in het huidige document, in plaats van in het aparte document waartoe de template-inhoud behoort. Zie de voorbeelden op de pagina van Node.cloneNode() voor meer details.
Merk op dat de DocumentFragment-container zelf geen gekoppelde data mag hebben. Zie het voorbeeld Data op het DocumentFragment wordt niet gekloond voor meer details.
Declaratieve shadow DOM
Als het <template>-element het attribuut shadowrootmode bevat met de waarde open of closed, genereert de HTML-parser onmiddellijk een shadow DOM. Het element wordt in de DOM vervangen door de inhoud ervan, verpakt in een ShadowRoot, die wordt gekoppeld aan het bovenliggende element.
Dit is het declaratieve equivalent van het aanroepen van Element.attachShadow() om een shadow root aan een element te koppelen.
Als het element een andere waarde heeft voor shadowrootmode, of het attribuut shadowrootmode niet heeft, genereert de parser een HTMLTemplateElement.
Evenzo geldt: als er meerdere declaratieve shadow roots zijn, wordt alleen de eerste vervangen door een ShadowRoot — latere exemplaren worden geparsed als HTMLTemplateElement-objecten.
Andere attributen die beginnen met shadowroot maken declaratieve aanpassing van de ShadowRoot mogelijk, zoals het bepalen hoe slots worden toegewezen.
Voorbeelden
Tabelrijen genereren
We beginnen met het HTML-gedeelte van het voorbeeld.
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>Eerst hebben we een tabel waarin we later met JavaScript-code inhoud zullen invoegen. Dan komt de template, die de structuur beschrijft van een HTML-fragment dat een enkele tabelrij vertegenwoordigt.
Nu de tabel is aangemaakt en de template is gedefinieerd, gebruiken we JavaScript om rijen in de tabel in te voegen, waarbij elke rij wordt geconstrueerd op basis van de template.
// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
if ("content" in document.createElement("template")) {
// Instantiate the table with the existing HTML tbody
// and the row with the template
const tbody = document.querySelector("tbody");
const template = document.querySelector("#productrow");
// Clone the new row and insert it into the table
const clone = document.importNode(template.content, true);
let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// Clone the new row and insert it into the table
const clone2 = document.importNode(template.content, true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// Find another way to add the rows to the table because
// the HTML template element is not supported.
}Het resultaat is de oorspronkelijke HTML-tabel, met twee nieuwe rijen die er via JavaScript aan zijn toegevoegd:
table {
background: black;
}
table td {
background: white;
}Een declaratieve shadow DOM implementeren
In dit voorbeeld wordt aan het begin van de opmaak een verborgen ondersteuningswaarschuwing opgenomen. Deze waarschuwing wordt later via JavaScript zichtbaar gemaakt als de browser het attribuut shadowrootmode niet ondersteunt. Vervolgens zijn er twee <article>-elementen, elk met geneste <style>-elementen met verschillend gedrag. Het eerste <style>-element is globaal voor het hele document. Het tweede is beperkt tot de shadow root die is gegenereerd in plaats van het <template>-element, vanwege de aanwezigheid van het attribuut shadowrootmode.
<p hidden>
⛔ Your browser doesn't support <code>shadowrootmode</code> attribute yet.
</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);Declaratieve shadow DOM met gedelegeerde focus
Dit voorbeeld laat zien hoe shadowrootdelegatesfocus wordt toegepast op een shadow root die declaratief wordt gemaakt, en welk effect dit heeft op focus.
De code declareert eerst een shadow root binnen een <div>-element, met het <template>-element met het attribuut shadowrootmode.
Dit toont zowel een niet-focusbare <div> met tekst als een focusbaar <input>-element.
Ook wordt CSS gebruikt om elementen met :focus blauw te stylen, en om de normale styling van het hostelement in te stellen.
<div>
<template shadowrootmode="open">
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>Het tweede codeblok is identiek, behalve dat het attribuut shadowrootdelegatesfocus is ingesteld, waardoor de focus wordt gedelegeerd aan het eerste focusbare element in de tree als een niet-focusbaar element in de tree wordt geselecteerd.
<div>
<template shadowrootmode="open" shadowrootdelegatesfocus>
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>Tot slot gebruiken we de volgende CSS om een rode rand toe te passen op het bovenliggende <div>-element wanneer dit focus heeft.
div:focus {
border: 2px solid red;
}De resultaten worden hieronder getoond.
Wanneer de HTML voor het eerst wordt weergegeven, hebben de elementen geen styling, zoals te zien is op de eerste afbeelding.
Voor de shadow root waarvoor shadowrootdelegatesfocus niet is ingesteld, kunt u overal klikken behalve op de <input>, en de focus verandert dan niet (als u het <input>-element selecteert, ziet het eruit als de tweede afbeelding).

Voor de shadow root waarvoor shadowrootdelegatesfocus is ingesteld, selecteert u door op de tekst te klikken (die niet focusbaar is) het <input>-element, aangezien dit het eerste focusbare element in de tree is.
Hierdoor krijgt ook het bovenliggende element focus, zoals hieronder wordt getoond.

Declaratieve shadow DOM met benoemde slottoewijzing
Dit voorbeeld laat zien hoe elementen aan slots in een shadow DOM kunnen worden toegewezen op basis van hun slot-attribuut (vergeleken met het name-attribuut van de slot).
HTML
Eerst definiëren we een <article>-element dat titel-, metadata- en artikelinhoudinformatie presenteert.
Het artikel bevat een <template>-element dat een shadow root wordt, vanwege de aanwezigheid van het attribuut shadowrootmode.
We hoeven het attribuut shadowrootslotassignment niet in te stellen, omdat benoemde slottoewijzing de standaard is.
De template definieert elementen met benoemde slots voor "header"- en "meta"-informatie, en een naamloze slot voor "body"-informatie. De elementen zijn verschillend gestyled, zodat ze eenvoudig van elkaar te onderscheiden zijn.
<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>
Text 1 with no slot attribute. Goes into default (unnamed) slot inside the
"body" div.
</p>
<span slot="title">Text for the title slot</span>
<span slot="meta">Text for the meta slot</span>
<p>
Text 2 with no slot attribute. Also goes into default (unnamed) slot inside
the "body" div.
</p>
</article>Onder dezelfde host, onder de template, hebben we vier elementen om de slots te vullen.
De <span>-elementen hebben slot-attributen die overeenkomen met de name-attributen van de slots in de template, en vullen de bijbehorende slots.
De twee <p>-elementen zijn naamloos, en worden dus beide ingevoegd in de naamloze <slot> in het "body"-element.
Resultaten
Het onderstaande voorbeeld toont de inhoud van de slots in de bijbehorende secties.
Declaratieve shadow DOM met handmatige slottoewijzing
Dit voorbeeld laat zien hoe elementen aan slots in een shadow DOM kunnen worden toegewezen met handmatige slottoewijzing.
Bij deze aanpak moet elk element handmatig aan een bepaalde slot worden toegewezen. Er is geen standaardtoewijzing, dus elke slot die niet is toegewezen, blijft leeg.
HTML
Eerst hebben we een verborgen ondersteuningswaarschuwing.
Deze waarschuwing wordt later via JavaScript zichtbaar gemaakt als de browser het attribuut shadowrootslotassignment niet ondersteunt.
<p id="support-warning" hidden>
⛔ Your browser doesn't support the
<code>shadowrootslotassignment</code> attribute yet.
</p>Vervolgens definiëren we een <article>-element dat titel-, metadata- en artikelinhoudinformatie presenteert.
Dit bevat een <template>-element dat een shadow root wordt, vanwege de aanwezigheid van het attribuut shadowrootmode, en dat handmatige slottoewijzing gebruikt omdat shadowrootslotassignment="manual" is ingesteld.
De template definieert elementen met slots voor "header"-, "meta"- en "body"-informatie, die afzonderlijk kunnen worden aangeduid via hun id-attribuut.
De elementen zijn verschillend gestyled, zodat ze eenvoudig van elkaar te onderscheiden zijn.
<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">Text for the title slot</span>
<span id="text_meta">Text for the meta slot</span>
<p id="text_body_1">Text 1 for body slot.</p>
<p id="text_body_2">Text 2 for body slot.</p>
</article>Onder dezelfde host, onder de template, hebben we vier elementen om de slots te vullen. Deze zijn ook door middel van een id geïdentificeerd.
JavaScript
De JavaScript voor handmatige slottoewijzing wordt hieronder getoond.
Eerst haalt de code de slots binnen de shadow root op, dan de tekst die moet worden ingevoegd, en ten slotte wijst deze de tekst toe aan de slot.
Merk op dat u een node slechts één keer aan een bepaalde slot kunt toewijzen, en dat als u meerdere nodes aan één slot toewijst met HTMLSlotElement.assign(), de volgorde waarin ze zijn opgegeven bepaalt in welke volgorde ze worden toegevoegd.
const host = document.querySelector("#host");
const shadow = host.shadowRoot;
// 1. Target your slots
const titleSlot = shadow.querySelector("#titleSlot");
const metaSlot = shadow.querySelector("#metaSlot");
const bodySlot = shadow.querySelector("#bodySlot");
// 2. Target the Elements to slot
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. Manually assign them
titleSlot.assign(titleText);
metaSlot.assign(metaText);
bodySlot.assign(body2Text, body1Text);De code toont de verborgen ondersteuningswaarschuwing als slottoewijzing niet wordt ondersteund.
const isShadowRootSlotAssignmentSupported = Object.hasOwn(
HTMLTemplateElement.prototype,
"shadowRootSlotAssignment",
);
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootSlotAssignmentSupported);Resultaten
Het onderstaande voorbeeld toont de inhoud van de slots in de bijbehorende secties.
Als het attribuut shadowrootslotassignment niet wordt ondersteund, wordt een waarschuwing getoond en gebruikt de browser named-toewijzing.
Omdat echter geen van de slots of de in te voegen elementen een naam heeft, worden alle elementen ingevoegd in de titel-slot (omdat dit de eerste naamloze slot is, en dus de "standaard"-slot).
Data op het DocumentFragment wordt niet gekloond
Wanneer een DocumentFragment-waarde wordt doorgegeven, verplaatsen Node.appendChild en vergelijkbare methoden alleen de child nodes van die waarde naar de doelnode. Daarom is het meestal beter om event handlers te koppelen aan de kinderen van een DocumentFragment, in plaats van aan het DocumentFragment zelf.
Bekijk de volgende HTML en JavaScript:
HTML
<div id="container"></div>
<template id="template">
<div>Click me</div>
</template>JavaScript
const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
event.target.append(" — Clicked this 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);Resultaat
Aangezien firstClone een DocumentFragment is, worden alleen de kinderen ervan toegevoegd aan container wanneer appendChild wordt aangeroepen; de event handlers van firstClone worden niet gekopieerd. Omdat daarentegen een event handler is toegevoegd aan de eerste child node van secondClone, wordt de event handler wel gekopieerd wanneer appendChild wordt aangeroepen, en werkt het klikken erop zoals verwacht.
Technische samenvatting
| Inhoudscategorieën | Metadata content, flow content, phrasing content, script-supporting element |
|---|---|
| Toegestane inhoud | Niets (zie Gebruiksaanwijzingen) |
| Weglaten van tags | Geen, zowel de begin- als de eindtag zijn verplicht. |
| Toegestane ouders |
Elk element dat
metadata content,
phrasing content, of
script-supporting elements
accepteert. Ook toegestaan als kind van een <colgroup>-
element dat geen
span-attribuut heeft.
|
| Impliciete ARIA-rol | Geen overeenkomstige rol |
| Toegestane ARIA-rollen | Geen role toegestaan |
| DOM-interface | HTMLTemplateElement |