如何创建自定义元素扩展类的新实例

Posted

技术标签:

【中文标题】如何创建自定义元素扩展类的新实例【英文标题】: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/2px`;
    //    div.style.left = `$x - div.clientWidth/2px`;
    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 中实现自定义的内置元素 【参考方案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+ :-)

【讨论】:

另外,请检查caniuse.com/#feat=custom-elementsv1 以获取更新的兼容性表

以上是关于如何创建自定义元素扩展类的新实例的主要内容,如果未能解决你的问题,请参考以下文章

XCUIElementQuery 将匹配自定义类的所有实例

创建自定义 xib 类的实例使手势识别器不起作用

如何生成扩展自定义记录类的 Doctrine 模型/类

自定义 Summernote 按钮以创建与类的链接

如何创建自定义可写转换器?

创建扩展/自定义控件的方法