What is the difference between window.customElements.define() and document.registerElement()

Viewed 5411

I have been reading some tutorials about web components (native, no polymer). I have seen two ways to register components and I'm a bit confused what to use. For the second one I actually receive a typescript error in vscode: [ts] Property 'registerElement' does not exist on type 'Document'. Did you mean 'createElement'?

/**
 * App
 */
export class App extends HTMLElement {

    constructor() {
        super();
    }

    connectedCallback() {
        this.innerHTML = this.template;
    }

    get template() {
        return `
        <div>This is a div</div>
        `;
    }
}

// What is the difference between these two methods?
window.customElements.define('vs-app', App);
document.registerElement('vs-app', App);
1 Answers

In terms of results, they accomplish pretty much the same. However, Document.registerElement() is deprecated, so you should use CustomElementRegistry.define() instead.

In my eyes, the key difference is that .registerElement() returns a constructor for the new element, whereas .define() allows you to specify the constructor, allowing for greater versatility. Consider the folowing examples:

var MyElement = document.registerElement('me-me');
document.body.appendChild(new MyElement());
var myElement = document.getElementsByTagName('me-me')[0];
myElement.textContent = 'I am a custom element.';

class MyElement extends HTMLElement {
  connectedCallback() {
    this.textContent = 'I am a custom element.';
  }
}
customElements.define('me-me', MyElement);
document.body.appendChild(new MyElement());

As you can see, using .define() allows you to specify the inner text beforehand, whereas you have to manually specify the text in the case of .registerElement(). Provided this is a very simple example to showcase my point, using .define(), you can add a lot more to the default behavior, appearance and content of a custom element than you can with .registerElement().

Related