Как создать новый экземпляр расширенного класса пользовательских элементов

Я пытаюсь пример с сайта разработчиков Google, и я получаю сообщение об ошибке: "TypeError: Неверный конструктор. Что не так и как это исправить?

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'});
let button = new FancyButton();
button.textContent = 'Fancy button!';
button.disabled = true;

2 ответа

Blink, веб-движок, который в настоящее время реализует Custom Element v1 (например, в Chrome v53+), поддерживает только автономные пользовательские элементы: см. Открытую ошибку Blink.

Если вы хотите определить настраиваемые встроенные элементы (т.е. <button> расширение), вам нужно будет использовать полифилл, такой как в Web Reflection.

Кроме того, вы все еще можете использовать синтаксис Custom Element v0 (document.registerElement).


Обновить

Начиная с Chrome v60 (июль 2017 г.), альфа-реализация настраиваемых встроенных элементов доступна под флагом. Однако это работает только для <p> а также <div> теги...


Обновление 2

Теперь (апрель 2018 года) он работает изначально с версиями Chrome v67 и выше:-)

class F_BTN extends HTMLButtonElement{
    constructor(){
        super(); // must call constructor from parent class
        this.addEventListener(...);
        .... // etc.
     }
}

теперь помогите customElements.define узнать что регистрируется

customElements.define("f-btn",F_BTN,{extends:'button'});
// <button></button> -- not TagName which is BUTTON
// HTMLAnchorElement -> 'a' ; HTMLInputElement -> 'input'

Вы можете создавать элементы, такие как:

<body>
 ....
 <f-btn>BTN_NAME</f-btn>
 ...
 </body>

или же

var elm = new F_BTN(...options); 
// F_BTN = customElements.get('f-btn') // in case F_BTN is out of scope

Проблема в том elm = document.createElement('f-btn') не работает Вот почему я использую что-то. лайк

_E = function (name, opt) {
  var $;
  switch (true) {
    case (name === '' || !name):
        {
            $ = document.createElement('div');
        }
        break; // create  div
    case (!name.indexOf('<')):
        {
            $ = document.createElement('div');
            $.innerHTML = name;
            $ = $.firstElementChild;
        }
        break;
    default:
        var c = window.customElements.get(name);
        if(c){ 
          return new c(opt);
        } else {
          document.createElement(name);
        }

  }
  if (opt)
      $.innerHTML = opt;
  return $;
};

var elm1 = _E('f-btn'); parent.appendChild(elm1);
Другие вопросы по тегам