【问题标题】:customElements not working in google chromecustomElements 在谷歌浏览器中不起作用
【发布时间】:2020-04-11 09:16:04
【问题描述】:

我正在尝试在我的网站中使用一些自定义元素,并且在 Firefox 中它到目前为止运行良好。然而,在谷歌浏览器中,它只是默默地失败了——我的自定义元素的构造函数永远不会被调用,它也不会抛出错误。

假设这个最小的例子:

<!DOCTYPE html>
<html>
    <head>
        <script>
            class MyElement extends HTMLDivElement {
                constructor(){
                    super();
                    this.style.background = "#00ff00";
                    console.log("Created custom element!");
                }
            }
            function addCustomElement(){
                customElements.define("my-element",MyElement,{extends:"div"});
                console.log("Added MyElement to custom element registry!");
            }
        </script>
    </head>
    <body onload="addCustomElement()">
        <my-element style="display:block;width:100px;height:100px;background:#ff0000"></my-element>
    </body>
</html>

我希望这会创建一个自定义元素类 MyElement,并将 DOM 中的所有 my-element-元素转换为该类的实例,一旦添加到自定义元素注册表,就会将原来的红色组件变为绿色。在 Firefox 中,这正是发生的情况,但在 google chrome 中,它保持红色。控制台表明该元素已添加到注册表中,但从未调用过它的构造函数。

我错过了什么吗?这是chrome的问题,还是我做错了什么?我怎样才能让它在那里工作?

【问题讨论】:

标签: javascript html google-chrome custom-element


【解决方案1】:

这里的工作示例

class MyElement extends HTMLElement  {
   constructor(){
   super();
   this.style.background = "#00ff00";
   console.log("Created custom element!");
   }
}
function addCustomElement(){
   customElements.define("my-element",  MyElement)  
   console.log("Added MyElement to custom element registry!");
}
// add call here, because onload did not work for me
addCustomElement()

https://jsfiddle.net/so98Lauz/1/

变化:

  • 扩展 HTMLElement 而不是 HTMLDivElement
  • 在js中调用addCustomElement函数以确保它被执行
  • customElements.define 中删除了{extends:"div"}

【讨论】:

  • 是的,将HTMLDivElement 更改为HTMLElement 并删除,{extends:"div"} 确实为我解决了这个问题。谢谢。另外,我刚刚注意到 mdn compatibility table 上说 chrome 支持“仅自治自定义元素”-我想这就是为什么扩展 HTMLDivElement 不起作用。
  • 知道为什么它不适用于{extends:"div"}HTMLDivElement 选项吗?根据developers.google.com,也支持此语法
  • 不幸的是我不知道,我只是试图让它工作并检查 google developer customelements docs accoriding to mozilla 它应该可以工作 mozilla CustomElementRegistry/define docs 但是当扩展不是 ` 时,chrome 向我显示了一个错误HTML元素`
【解决方案2】:

我刚刚又检查了mdn,发现了这个:

有两种类型的自定义元素:

  1. 自治自定义元素是独立的——它们不继承自标准 HTML 元素。您可以通过将它们写成 HTML 元素来在页面上使用它们。例如&lt;popup-info&gt;document.createElement("popup-info")
  2. 自定义的内置元素继承自基本的 HTML 元素。要创建其中之一,您必须指定它们扩展的元素(如上面示例中所暗示的那样),并且通过写出基本元素但在 is 属性(或属性)中指定自定义元素的名称来使用它们。例如&lt;p is="word-count"&gt;document.createElement("p", { is: "word-count" })

这意味着由于MyElement 扩展了HTMLDivElement,正确的语法应该是&lt;div is="my-element"&gt;,而不是&lt;my-element&gt;。 Firefox 似乎仍然接受&lt;my-element&gt;,但 chrome 不接受。

使用正确的语法,这似乎适用于两种浏览器:

<!DOCTYPE html>
<html>
    <head>
        <script>
            class MyElement extends HTMLDivElement {
                constructor(){
                    super();
                    this.style.background = "#00ff00";
                    console.log("Created custom element!");
                }
            }
            function addCustomElement(){
                customElements.define("my-element",MyElement,{extends:"div"});
                console.log("Added MyElement to custom element registry!");
            }
        </script>
    </head>
    <body onload="addCustomElement()">
        <div is="my-element" style="display:block;width:100px;height:100px;background:#ff0000"></div>
    </body>
</html>

mdn 上还有一条注释指出 chrome 仅支持自治元素;然而,这似乎不是真的,因为上面的 sn-p 似乎工作得很好。

【讨论】:

  • (1) 不需要addCustomElement 函数,可以在加载事件之前(或之后很久)定义元素。 (2)Opera 和 Safari 尚不支持自定义内置元素 (=extended),有一个 Polyfill (3)当您使用 document.createElement 创建一个元素时,is 属性是 not 在元素上设置.. 如果您需要它(例如,对于 CSS 选择器),您必须在您的 connectedCallback 中执行 .setAttribute("is","my-element"); (4) 注意!您可以使用 is 属性将元素更改为其他内容
  • 关于扩展 IMG 元素的利弊,请参阅:cardmeister.github.io
猜你喜欢
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
  • 2016-01-25
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多