【问题标题】:How to create new instance of an extended class of custom elements如何创建自定义元素扩展类的新实例
【发布时间】:2017-02-20 12:20:42
【问题描述】:

我正在尝试来自 google developer site 的示例,但出现错误:“TypeError: Illegal constructor. 出了什么问题以及如何解决?

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;

【问题讨论】:

  • 您使用的是什么浏览器(版本)?
  • 当前浏览器都不支持Custom Elements v1
  • 来自开发者网站:Chrome 54(状态)具有自定义元素 v1。 Safari 已经开始原型设计,您可以每晚在 WebKit 中测试 API。 Edge 已经开始原型设计。 Mozilla 有一个开放的错误要实施。
  • Safari 不会在第一次 AFAIK 中实现自定义的内置元素

标签: javascript html ecmascript-6 web-component custom-element


【解决方案1】:
class F_BTN extends HTMLButtonElement{
    constructor(){
        super(); // must call constructor from parent class
        this.addEventListener(...);
        .... // etc.
     }
}

customElements.define("f-btn",F_BTN,{extends:'button'});

使用内联:

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

或从 javascript 创建追加

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') 不起作用。

这就是我创建自定义 create_element 函数的原因_E

_E = function (name, html) {
  var $;
  switch (true) {
    case (name === '' || !name):  // _E()  -- a div
        {
            $ = document.createElement('div');
        }
        break; 
    case (!name.indexOf('<')):  // _E('<h1><i>abc</i><b>A</b></h1>')  -- sub_dom
        {
            $ = document.createElement('div');
            $.innerHTML = name;
            $ = $.firstElementChild;
        }
        break;
    default:
        var c = window.customElements.get(name);
        if(c){ 
          $ = new c();   // _E('f-btn')  -- customElement
        } else {
          $ = document.createElement(name); // _E('button')  -- htmlElement
        }   
  }      
  if (html) $.innerHTML = html;
  return $;
};

var elm1 = _E('f-btn'); parent.appendChild(elm1);

【讨论】:

  • customElements.define 方法中添加extends 选项对我有用。谢谢。
【解决方案2】:

Blink,目前实现Custom Element v1(以Chrome v53+为例)的web引擎只支持autonomous custom elements:见openBlink bug

如果你想定义customized built-in elements(即&lt;button&gt;扩展),你需要使用像the one from Web Reflection这样的polyfill。

或者,您仍然可以使用自定义元素 v0 语法 (document.registerElement)。


更新 #3

自 2018 年 10 月以来,它们原生支持 Chrome 67+ 和 Firefox 63+ :-)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
相关资源
最近更新 更多