Search code examples
javascripthtmlweb-componentcustom-elementgoogle-web-component

How to extend default HTML elements as a "customized built-in element" using Web Components?


I am looking to learn how to extend default HTML elements using the newer HTML5 Web Component spec. I have tried the examples outlined by Google here: https://developers.google.com/web/fundamentals/getting-started/primers/customelements

They are:

Anonymous function:

customElements.define('bigger-img', class extends Image {
  // Give img default size if users don't specify.
  constructor(width=50, height=50) {
    super(width * 10, height * 10);
  }
}, {extends: 'img'});

in HTML as:

<img is="bigger-img" width="15" height="20">

and

Named function:

// See https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
// for the list of other DOM interfaces.
class FancyButton extends HTMLButtonElement {
  constructor() {
    super(); // always call super() first in the ctor.
    this.addEventListener('click', e => this.drawRipple(e.offsetX, e.offsetY));
  }

  // Material design ripple animation.
  drawRipple(x, y) {
    let div = document.createElement('div');
    div.classList.add('ripple');
    this.appendChild(div);
    div.style.top = `${y - div.clientHeight/2}px`;
    div.style.left = `${x - div.clientWidth/2}px`;
    div.style.backgroundColor = 'currentColor';
    div.classList.add('run');
    div.addEventListener('transitionend', e => div.remove());
  }
}

customElements.define('fancy-button', FancyButton, {extends: 'button'});

in HTML as:

<button is="fancy-button" disabled>Fancy button!</button>

I can't get either of these examples to work in Chrome 55. What could be going on that creating customized built-in elements does not work? I have tried putting the JS and HTML in different order and swapping out HTMLImageElement for Image in example. Any help would be greatly appreciated!


Solution

  • It's because Customized Built-In Elements are not implemented yet in Chrome / Opera. Check status of the Chromium devs in this issue.

    Only Autonomous Custom Elements are already implemented natively.

    Menwhile you should use a a polyfill like WebReflection's one.

    Update since Chrome 67

    Now it works with versions of Chrome version 67 and above.