【问题标题】:Why does childNodes return a different value in connectedCallback if type="module" is set?如果设置了 type="module",为什么 childNodes 在 connectedCallback 中返回不同的值?
【发布时间】:2021-10-15 06:41:30
【问题描述】:

调用this.childNodes 而不是自定义元素的connectedCallback 将返回不同的值,具体取决于是否在脚本标记中设置了type="module"

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <script>

    class CustomElement extends HTMLElement {
      connectedCallback() {
        console.log(this.childNodes);
      }
    }
    customElements.define('custom-element', CustomElement);

  </script>
</head>

<custom-element><div></div></custom-element>

</html>

在我的浏览器中,记录了以下内容,表示有0个子节点:

NodeList []

但如果我在脚本标签中设置type="module",则会记录1个子节点:

NodeList [ div ]

我能够在 Firefox 90 和 Chrome 92 上复制此行为。

为什么设置type="module"会改变childNodes的返回值?

【问题讨论】:

    标签: javascript html web-component es6-modules custom-element


    【解决方案1】:

    我想我找到了答案。

    this.childNodes 在脚本不是模块时在connectedCallback 中返回 0 个节点,因为脚本会立即执行,而当设置了type="module" 时,脚本在文档被解析后执行,所以this.childNodes 返回 1节点。

    模块脚本

    当设置type="module" 时,脚本会自动延迟。在这种情况下,直到文档完成加载并被解析后,脚本才会运行。

    推迟

    此布尔属性设置为向浏览器指示脚本应在文档被解析之后但在触发 DOMContentLoaded 之前执行。

    在这种情况下,文档的readyStateinteractive

    非模块脚本

    对于常规的非模块脚本,脚本会立即执行,因此文档仍在加载,元素的子节点不可用。

    没有 async 、 defer 或 type="module" 属性的脚本以及内联脚本会在浏览器继续解析页面之前立即获取并执行。

    这里文档的readyStateloading


    来源

    【讨论】:

      【解决方案2】:

      因为模块强制脚本在整个 DOM 被解析后运行。

      在 SO 上搜索 settimeout 和 connectedcallback

      【讨论】:

        猜你喜欢
        • 2023-04-05
        • 1970-01-01
        • 2023-04-01
        • 2014-02-10
        • 2011-10-03
        • 2013-08-14
        • 1970-01-01
        • 2012-07-28
        相关资源
        最近更新 更多