自定义元素适用于 Safari 但不适用于 Firefox 和 Chrome

Custom elements works for Safari but not for Firefox and Chrome

我确定我遗漏了规范中的一些基本内容,但是在 Safari 上的 Mac 运行 上构建了大量自定义元素后,我发现它们不起作用在 Firefox 和 Chrome 上。我错过了什么?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>NoCE</title>
        <script>
            class NoCE extends HTMLElement {
                constructor(args) {
                    super();
                }

                connectedCallback() {
                    this.innerHTML = "<p>It Works</p>";
                }

                attributeChangedCallback(name, oldValue, newValue, namespaceURI) {}

                disconnectedCallback() {}

                adoptedCallback() {}

                static get observedAttributes() { return []; }
            }

            customElements.define("no-ce", NoCE, { extends: "div" });
        </script>
    </head>
    <body>
        <no-ce>
            No custom elements
        </no-ce>
    </body>
</html>

在 Safari 中,页面显示 "It Works"。在 Firefox 和 Chrome 中显示 "No Custom Elements"(运行 on Mac OS X.)

野生动物园 12.0.2 火狐 64.0.2 Chrome71.0.3578.98

您混淆了自主自定义元素(又名新HTML标签)和自定义内置元素(又名标准 HTML 元素扩展),语法略有不同。

对于自治自定义元素

class NoCE extends HTMLElement
...
customElements.define( 'no-ce', NoCE )
...
<no-ce><no-ce>

对于 自定义内置 <div> 元素:

class NoCE extends HTMLDivElement
...
customElements.define( 'no-ce', NoCE, { extends: 'div'} )
...
<div is='no-ce'></div>

Safari 不实现自定义的 buit-it 元素,因此将忽略 extends 选项并将您的代码作为简单的自主自定义元素处理。

另一方面,Chrome 和 Firefox 将忽略您的自定义元素定义,因为它不正确。


如果你想让你的自定义元素继承自 <div>,你应该先用 HTMLDivElement 扩展 NoCE class,然后使用 <div is="no-ce"> 句法。 (但如果没有 polyfill,那将无法在 Safari 中使用。)

或者,如果您想创建自己的具有基本 <div> 行为的 HTML 标签,您可以定义一个自主的自定义元素并将 {display:block} CSS风格。

class ACE extends HTMLElement {
  connectedCallback() {
    this.attachShadow( { mode: 'open' } )
        .innerHTML = `<style> :host { display: block } </style>
                      Autonomous CE works`
  }
}
customElements.define( 'a-ce', ACE )


class CBE extends HTMLDivElement {
  connectedCallback() {
    this.attachShadow( { mode: 'open' } )
        .innerHTML = `Customized DIV works`
  }
}
customElements.define("c-ce", CBE, { extends: "div" } )
<a-ce>autonomous custom element not implemented</a-ce>

<div is="c-ce">customized built-in element not implemented</div>