If I write a template node into the HTML by hand I can use it in my custom element just fine. If I create a template node and append it to the HTML using javascript when I try to use it, it's empty...
in the example below I make template-a the regular HTML way and make template-b to be the same shape using javascript. I define a very simple custom element that uses both templates. only template-a is visible.
const sandbox = document.getElementById('sandbox')
const slot = document.createElement('slot')
slot.setAttribute('name', 'b')
slot.append('slot content goes here')
const em = document.createElement('em')
em.append(slot, '?')
const createdTemplate = document.createElement('template')
createdTemplate.setAttribute('id', 'template-b')
createdTemplate.append(em)
sandbox.append(createdTemplate)
customElements.define('test-element', class extends HTMLElement {
constructor () {
super()
this.attachShadow({ mode: 'open' }).append(
...['template-a','template-b']
.map(id =>
document.getElementById(id).content.cloneNode(true)
)
)
}
})
<div id="sandbox">
<template id="template-a">
<strong><slot name="a">slot content goes here</slot>!</strong>
</template>
<test-element>
<span slot="a">some a slot content</span>
<span slot="b">some b slot content</span>
</test-element>
</div>
Some notes on your code:
this.shadow = this.attachShadow({ mode: 'open' })
can become
this.attachShadow({ mode: 'open' })
this creates/sets this.shadowRoot for free
Note that .appendChild(el) takes one element
and .append() takes an Array
Only difference is appendChild() returns a reference to the inserted element,
and append() returns nothing
So you can write:
em.appendChild(slot)
em.appendChild(document.createTextNode('?'))
as
em.append(slot, document.createTextNode('?'))
If you have Nodes in an Array:
let myElements = [slot, document.createTextNode('?')];
you can use the ES6 spread opperator:
em.append(...myElements)
This means you can write:
this.shadow.appendChild(document.getElementById('template-a').content.cloneNode(true))
this.shadow.appendChild(document.getElementById('template-b').content.cloneNode(true))
as:
this.shadowRoot
.append(
...['a','b']
.map(templ => document.getElementById(`template-${templ}`).content.cloneNode(true))
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With