只有在DOM准备就绪后才开始操作DOM,这是一种古老的常识,我们可以确定所有元素都可用,并且在jQuery之后,我们都为此使用了 DOMContentLoaded 事件。

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

第一个问题:
DOMContentLoaded与(自治)自定义元素有何关系?仅在所有组件connectedCallbacks完成后才发生该事件吗?如果不是,我如何确保某些代码仅在Web组件完成初始化后才执行?

第二个问题,完全相关:

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

最佳答案

我不喜欢Web组件,但是我会说……根本不。

您的组件是由脚本定义的,但是在此之前,浏览器仍然会解析标记并照常执行所有同步脚本,并在完成后触发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");
}
<my-custom></my-custom>


但是,如果您确实等待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");
}
<my-custom></my-custom>


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

关于您的最后一个问题,关于defer属性的in the docs说,具有此类属性的脚本将在DOMContentLoaded触发
之前被解析为

关于javascript - DOMContentLoaded与Web组件有何关系?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51362204/

10-13 06:52