Web 组件的行为有所不同,具体取决于是否使用“defer”

Ach*_*him 1 web-component typescript

我在 TypeScript 中实现了一个 WebComponent,如下所示,并通过 WebPack 捆绑:

class MyTestComponent extends HTMLElement {
    // ...
    connectedCallback() {
        this.config = JSON.parse(this.innerText);
// ...
customElements.define("my-test", MyTestComponent);
Run Code Online (Sandbox Code Playgroud)

在网页中它的使用方式如下:

<my-test>
{
  "parts": [
    [3, "red"]
  ]
}
</my-test>
Run Code Online (Sandbox Code Playgroud)

This worked fine using my WebPack genrated test page, but failed if I included the component into another page. I spend some time until I figured out that the defer attribute at the including script tag makes the difference. If I use defer the component works fine. If not this.innerText is empty when connectCallback is called.

I would like to understand why defer makes a difference and what's going on in detail. Can somebody explain?

Dan*_*man 5

它与 TypeScript 或 WebPack 无关。这是标准的 Web 组件行为。

在开始connectedCallback标签上触发,其内部内容尚未解析。

解析 DOM 中的所有内容defer声明自定义元素

因此,为了在使用之前定义自定义元素时使其正常工作,

你必须延迟执行,直到组件 DOM ( innnerText or innerHTML) 被解析。

最简单的方法是延迟直到事件循环为空:

connectedCallback() {
  setTimeout(()=>{
    this.config = JSON.parse(this.innerText);
  });
}
Run Code Online (Sandbox Code Playgroud)

长答案(当 FirefoxconnectedCallback延迟启动时,2021 年 3 月之前)

基础类工具,如 FAST、Lit、LWC 和 Hybrids,可以保护您免受这种标准行为的影响……
让您学习工具,而不是技术。