自定义元素构造函数中的属性缺少依赖于脚本标记位置

Attributes in custom element constructor missing dependent on script tag location

我尝试让 html 自定义元素起作用:

在浏览器中查看以下示例时,我必须得出结论,constructor() 中的 this.dataset.text 属性是:

<html>
    <head>
        <title>myimage</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
        before custom element definition: <my-element data-text="Replaced and works as expected">Not Replaced</my-element>
        </div>
        <script>
          class MyElement extends HTMLElement {
            constructor() {
              super();
              this.text_attribute= this.dataset.text;
            }

            connectedCallback() {
              if (this.text_attribute) {
                this.innerText = this.text_attribute;
              }
            }
          }
          customElements.define('my-element', MyElement);
        </script>
        <div>
        after custom element definition: <my-element data-text="Replaced">Not Replaced</my-element>
        </div>
    </body>
</html>

这似乎是 chrome 和 Firefox 中的常见行为。我可以提供更多事实:

任何人都可以解释这种看似有问题的行为的目的吗?

这不是错误行为。

您的第一个 <my-element> 由 DOM 解析器处理 在您定义它之前
因此,当 constructor 执行时,所有属性都是已知的(在 DOM 中)。

通常您不会在 constructor 中访问 DOM;因为当你这样做时它也会 运行s:

 let foo = document.createElement("my-element"); // absolutly no DOM created

这是一个简化的例子:

<style>
  my-element { display:block }
</style>
<my-element id="FOO"> ONE </my-element>
<script>
  customElements.define('my-element', class extends HTMLElement {
    constructor() {
      super();
      document.body.append(` ► constructor id:${this.id} ◄ `);
    }
    connectedCallback() {
      document.body.append(` ► connected id:${this.id} ◄ `);
    }
  });
</script>
<my-element id="BAR"> TWO </my-element>
<my-element id="BAZ"> THREE </my-element>

注意

  • 如何将 FOO innerHTML 写入(因为它已被解析)到 DOM before 它的 constructor 运行s

  • BARBAZ构造函数运行如何在之前将其innerHTML写入DOM
    id 还不存在

  • 我看过很多课程,他们通过执行 <script> async 来“拯救”你免受这种标准行为的影响,毕竟 DOM 被解析。他们不懂技术...