Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript created template element not working [duplicate]

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>
like image 536
dtudury Avatar asked Apr 01 '26 03:04

dtudury


1 Answers

Some notes on your code:

this.shadowRoot

this.shadow = this.attachShadow({ mode: 'open' })

can become

this.attachShadow({ mode: 'open' })

this creates/sets this.shadowRoot for free

appendChild vs. append

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))
  )
like image 59
Danny '365CSI' Engelman Avatar answered Apr 03 '26 18:04

Danny '365CSI' Engelman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!