扩展另一个自定义元素?

Extending another custom element?

正在尝试扩展自定义元素:

class ABC extends HTMLDivElement {
  connectedCallback() { console.log('ABC here') }
}

customElements.define("x-abc", ABC, {
  extends: 'div'
})

class XYZ extends ABC {
  connectedCallback() { console.log('XYZ here') }
}

customElements.define("x-xyz", XYZ, {
  extends: 'x-abc'
})
<div is="x-abc"></div>
<div is="x-xyz"></div>

但出现此错误:

 Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': "x-abc" is a valid custom element name

错误令人困惑,因为它说 'is valid',而不是 'is not valid'!!

另一方面,FF 说:

  Uncaught DOMException: CustomElementRegistry.define: 'x-xyz' cannot extend a custom element

我想构建自定义元素的层次结构。

这个错误乍一看可能很混乱,但实际上很清楚。该规范清楚地定义了您只能使用 is 语法扩展内置函数。按照目前的设计,使用 ABC 作为基础 class 绝对不是最聪明的想法(直到你放弃扩展 HTMLDivElement 以支持 HTMLElement)。

您没有解释为什么需要扩展 div 元素,这绝对不是您通常构建组件层次结构的基础。 Safari 甚至不支持(可能永远不会)。

而是扩展 HTMLElement,并省略 is 语法。

class ABC extends HTMLElement {
  connectedCallback() {
    console.log('ABC here')
  }
}

customElements.define('x-abc', ABC)

class XYZ extends ABC {
  connectedCallback() {
    super.connectedCallback();
    console.log('XYZ here')
  }
}

customElements.define('x-xyz', XYZ)
<x-abc></x-abc>
<x-xyz></x-xyz>

如果出于某种奇怪的原因你需要继续扩展 HTMLDivElement(而不是 HTMLElement,这才是正确的方法),你可以这样做:

只需将 {extends: 'x-abc'} 部分替换为 {extends: 'div'}

您的两个组件都扩展了 div(它们的定义标签名称)。

class ABC extends HTMLDivElement {
  connectedCallback() {
    console.log('ABC here')
  }
}

customElements.define('x-abc', ABC, {
  extends: 'div'
})

class XYZ extends ABC {
  connectedCallback() {
    super.connectedCallback();
    console.log('XYZ here')
  }
}

customElements.define('x-xyz', XYZ, {
  extends: 'div'
})
<div is="x-abc"></div>
<div is="x-xyz"></div>