DOMContentLoaded如何与Web组件相关?

con*_*exo 7 javascript deferred-loading web-component domcontentloaded

只有在准备好DOM之后才开始操作DOM是一个古老的常识,我们可以确定所有元素都可用,并且在jQuery之后的日子里我们都使用了这个DOMContentLoaded事件.

现在,Web组件(特别是以自治自定义元素的形式)倾向于创建自己的HTML,通常在connectedCallback()生命周期方法中.

第一个问题:

如何DOMContentLoaded与(自治)自定义元素相关?只有在所有组件connectedCallbacks完成后才会发生事件吗?如果没有,我如何确保某些代码仅在Web组件初始化后执行?

第二个问题,完全相关:

Web组件如何与元素的defer属性相关联script

Kai*_*ido 2

我不喜欢网络组件,但我想说……一点也不。

您的组件由脚本定义,但在此之前,浏览器仍将像往常一样解析标记并执行所有同步脚本,并在完成后触发 DOMContentLoaded。

因此,如果您在DOMContentLoaded 事件触发之前同步定义 CustomElements ,那么您的元素connectedCallback将被触发(因为它不是一个事件,它是一个回调,并且被同步调用)。

if (window.customElements) {

  addEventListener('DOMContentLoaded', e => console.log('DOM loaded'));

  class MyCustom extends HTMLElement {
    connectedCallback() {
      console.log('Custom element added to page.');
    }
  }

  customElements.define('my-custom', MyCustom);
  console.log('Just defined my custom element')

} else {
  console.log("your browser doesn't have native support");
}
Run Code Online (Sandbox Code Playgroud)
<my-custom></my-custom>
Run Code Online (Sandbox Code Playgroud)

但如果您确实等待 DOMContentLoaded 事件,那么...回调将在之后触发。

if (window.customElements) {

  addEventListener('DOMContentLoaded', e => console.log('DOM loaded'));

  class MyCustom extends HTMLElement {
    connectedCallback() {
      console.log('Custom element added to page.');
    }
  }

  setTimeout(()=> customElements.define('my-custom', MyCustom), 2000);

} else {
  console.log("your browser doesn't have native support");
}
Run Code Online (Sandbox Code Playgroud)
<my-custom></my-custom>
Run Code Online (Sandbox Code Playgroud)

但 DOMContentLoaded 除了所有脚本的同步执行结束之外不会等待任何其他事情,就像其中没有任何 CustomElement 一样。


至于你的最后一个问题,正如有关属性的文档中defer所述,具有此类属性的脚本将在DOMContentLoaded 触发之前被解析。

  • @LGSon 网络组件 ;-) (3认同)