Custom elements works for Safari but not for Firefox and Chrome

筅森魡賤 提交于 2020-02-04 22:56:24

问题


I'm sure I'm missing something fundamental from the spec, but after building a large set of custom elements on the Mac running on Safari, I find they don't work on Firefox and Chrome. What am I missing?

<!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>

In Safari the page shows "It Works". In Firefox and Chrome it shows "No Custom Elements" (running on Mac OS X.)

Safari 12.0.2 Firefox 64.0.2 Chrome 71.0.3578.98


回答1:


You mixed up definitions of autonomous custom element (aka new HTML tag) with customized buit-in element (aka standard HTML element extension) which have a slightly different syntax.

For Autonomous Custom Element:

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

For Customized Built-in <div> Element:

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

Safari doesn't implement customized buit-it elements, and therefore will ignore the extends option and process your code as a simple autonomous custom element.

On the other hand, Chrome and Firefox will ignore your custom element definition because it is not correct.


If you want to make your custom element inherit from <div> you should first extend the NoCE class with HTMLDivElement, and then use the <div is="no-ce"> syntax. (But that won't work in Safari without a polyfill.)

Alternately, if you want to create your own HTML tag with a basic <div> behavior, you could define an autonomous custom element and apply to it the {display:block} CSS style.

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>


来源:https://stackoverflow.com/questions/54160445/custom-elements-works-for-safari-but-not-for-firefox-and-chrome

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!