在自定义元素中设置属性的正确位置

问题描述 投票:0回答:1

最小重现 - js 代码部分,第 5 行。

class Bazooka extends HTMLElement {
  host;
  constructor() {
    super();
    this.className = "hi"; // why ?? see bullet number - 5 --> https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance
    this.host = this.attachShadow({ mode: "open" });
  }

  connectedCallback() {
    let foo = document.querySelector(".test");
    this.host.appendChild(foo.content);
  }
}

customElements.define("bazooka-show", Bazooka);
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
  </head>
  <body>
    <main>
      <bazooka-show></bazooka-show>
    </main>
    <template class="test">
      <p>A shadow DOM.</p>
    </template>
  </body>
</html>

根据 html 规范 - https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance 要点 - 5,

constructor()
不应该获得属性,对吗?

该元素不得获得任何属性或子元素

我的问题是 - 为什么自定义元素接受属性(className)?浏览器不应该抛出错误吗?

html web-component custom-element
1个回答
0
投票

类的构造函数用于根据该类及其扩展的类实例化一个对象。在构造函数中,对象(this)被创建/已经存在。对象可以具有任何属性,因此在构造函数中设置

this.className
this.id
this.foo
是完全可以的。直接回答你的问题:不,它不应该抛出错误。在对象上设置任何属性都可以。

恰好创建的对象继承自

HTMLElement
,并且它神奇地绑定到 DOM 元素,并且在这样做时,创建了与对象上的匹配属性关联的属性。

在示例中,我在构造函数中添加了更多属性。您可以看到 id 最终也作为一个属性。如果您尝试设置像

this.nodeName
这样的属性,您会发现收到错误,因为它是从 HTMLElement 继承的只读属性。

class Bazooka extends HTMLElement {
  host;
  constructor() {
    super();
    this.className = "hi";
    this.id = "id01";
    this.foo = "bar";
    //this.nodeName = "error";
    this.host = this.attachShadow({ mode: "open" });
  }

  connectedCallback() {
    let foo = document.querySelector(".test");
    this.host.appendChild(foo.content);
  }
}

customElements.define("bazooka-show", Bazooka);
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
  </head>
  <body>
    <main>
      <bazooka-show></bazooka-show>
    </main>
    <template class="test">
      <p>A shadow DOM.</p>
    </template>
  </body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.