How do I append a Web Component created programmatically?
Asked Answered
C

2

6

I created a Web Component class to extend div, and used customElements.define() to define it:

class Resize_Div extends HTMLDivElement {
  constructor(){
      super();
      this.cpos = [0,0];
      <etc.>
  }
  connectedCallback() {
    console.log( 'connected' );
  }
  <etc.>
}

customElements.define('resize-div', Resize_Div, { extends:'div'} );

If I test in html, as <div is:'resize-div'> </div>, it works fine.

Now I want to use createElement to create an instance programmatically, using the options to declare the is, as documented here:

let dv = document.createElement('ul', { is: 'resize-div' })

The browser developer tools show it created, with outerHTML as below:

outerHTML: "<div is="resize-div"></div>"

As documented, "The new element [has] an is attribute whose value is the custom element's tag name."

Now I set id, class, and style, and attach the new element to the DOM via:

document.getElementById( parent ).appendChild( dv );

Now look at it again: the is attribute is stripped off and it doesn't function as a Web Component:

attributes: NamedNodeMap
0: id
1: class
2: style
length: 3

The docs for the deprecated registerElement here show an example using document.body.appendChild( new myTag() ), but that's obsolete.

So what is the correct way to create a Web Component programmatically and attach it to a document?

(ps. I'm working on Chromium Version 70.0.3538.67 (Official Build) Built on Ubuntu, running on Ubuntu 16.04 (64-bit)

Conservatory answered 15/2, 2019 at 22:55 Comment(0)
C
10

You've defined an extended <div> but you try to create a <ul> element.

If you create a <div> instead it will work:

let dv = document.createElement('div', { is: 'resize-div' })

The new syntax also works:

document.body.appendChild( new Resize_Div )

NB: When you create an customized built-in element programmatically the is attribute is not added in the HTML code but it still acts as a custom element, and outerHTML will return the HTML with is correctly populated as explained in the specs.

Cleek answered 15/2, 2019 at 23:37 Comment(0)
V
1

You can also create the element without this {is: 'tag'} object. May or may not be useful in some situations.

class MyElement extends HTMLElement {
  constructor() {
    super()
    const shadow = this.attachShadow({
      mode: 'open'
    })
    shadow.append(Object.assign(
      document.createElement('h1'), {
        textContent: 'Impossibru!'
      },
    ))
  }
}

customElements.define('my-custom-element', MyElement)
const el = document.createElement('my-custom-element')
document.body.append(el)
Vieira answered 7/6, 2021 at 1:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.