I want to instantiate a web component based on a <template>
element in the DOM using JS to set 2 slot values title
and text
.
template HTML
<template id="tiddler-display">
<div class="tiddler">
<h1><slot name="title">TITLE</slot></h1>
<p><slot name="text">TEXT</slot></p>
</div>
</template>
How does one insert ‘foo’ and ‘bar’ into the text/tile slots?
customElements.define(
'tiddler-display',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('tiddler-display');
let templateContent = template.content;
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(templateContent.cloneNode(true));
}
},
);
// Instantiate
let newElement = document.createElement('tiddler-display');
// How to insert 'foo' and 'bar' into the text/tile slots?
newElement.shadowRoot.querySelectorAll('slot')[0].innerHTML = 'foo';
// This cannot be the best way 👆
2
Answers
TL;DR : https://jsfiddle.net/zL8gapn2/15/
Hi,
What you did works fine, however if you have a lot of slots and want to reuse the template, it can be a bit long…
I use string templating for this :
What you can do is create a js object that fits your template
The you could get the html inside the template
Then you create a Function object, and call it providing your js object
I’ve worked a bit with templates lately, and that’s how I proceed.
Your
<template>
defines what is in shadowDOMlightDOM needs to provide the content for the
<slot>
elements reflected in shadowDOMWhen you do
document.createElement("tiddler-display")
you create the
<tiddler-display>
HTML Node, but without lightDOM content insideSee below code
<tiddler-display>
with content to be slotted (aka reflected) from lightDOM to shadowDOMinstantiate( )
function that programmaticaly creates the Web Component,and sets its lightDOM content
DOM parts
The other answer uses Template Literals to set content. Different solution, that works
(but the shown solution has no Web Component code).
You can apply this to Web Components as well. Make it fancy to extract the slot names from the template, whatever you need.
If you have a lot of templates/content you might want to check out the
Google Lit BaseClass for Web Components, it does all of the Template Literal heavylifting for you: https://lit.dev/
Note that the Lit (Template Literal) solution will be obsolete within the next year (or two)
The Web Components standards body is very active on bringing DOM Parts into the standard.
See DOM Parts in https://github.com/WICG/webcomponents/tree/gh-pages/proposals
Declarative shadowDOM
Note you can create one Web Component without any JavaScript
Great for SSR or rapid development (write HTML first, once it works create the optimized JS version)