在主体树中执行脚本时 DOM 准备好了吗?

Posted

技术标签:

【中文标题】在主体树中执行脚本时 DOM 准备好了吗?【英文标题】:Is the DOM ready when a script is executed within the body tree? 【发布时间】:2017-04-14 01:52:16 【问题描述】:

我有一个片段放在任何网站内,在文档中间,就像在文章中间,而不是在 <head> 内。该脚本通过附加<script> 标签在我的域上加载一个外部脚本(很像谷歌分析sn-p 所做的)。

我的问题是,如果该脚本放置在正文中,DOM 是否尚未被解析,所以我可以放心地假设我可以在评估我的脚本时操作 DOM 而无需等待 DOMReady 事件?

我问是因为当我的脚本开始执行和 DOMReady 事件触发时有很大的延迟(请参阅棕色条)。我正在使用这个DOMReady implementation

托管网站

<html>

<head>
  ...
</head>

<body>
  Website content
  ...
  <div>
    
  <!-- Snippet -->
  <div id="myContainer"></div> <!------(I should be able to query this div) -->
  <script type="text/javascript">
    function() 
      var ga = document.createElement('script');
      ga.type = 'text/javascript';
      ga.async = true;
      ga.src = 'http://example.com/script.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga, s);
    )();
  </script>
  <!-- Snippet End -->
  
  <div>
  More content
  ...
</body>
</html>

example.com/ script.js

(function()
    //by this time div#myContainer should exist, right?
    var div = document.getElementById('myContainer');
    div.innerHTML = "Hello World!";
)();

一些注意事项:

我无法控制主机页面,它可以包含任何内容。 对旧浏览器的支持是一个问题。 我应该能够尽快追加内容,我等不及其他库和图像之类的内容加载完毕。 它应该每次都能可靠地工作。

【问题讨论】:

第一个脚本元素之前的所有元素都已经存在。 我能看到的唯一可能的问题是,如果您的脚本在加载视频或大图像等大量媒体资产之前加载。但是,如果您不关注媒体数据,则不必担心。而且,如果您的目标是一个已知的选择器,您仍然可以将 onload 侦听器附加到这些元素。 【参考方案1】:

是的,没错。如果您在正文底部有一个脚本标签,那么当您的脚本运行时,所有内容都会在此之前呈现。

W3Schools 有一篇关于这个主题的好文章。

&lt;head&gt; 中的脚本

在调用它们或触发事件时要执行的脚本被放置在函数中。 把你的函数放在 head 部分,这样它们都在一个地方,它们不会干扰页面内容。

&lt;body&gt; 中的脚本

如果您不希望将脚本放在函数中,或者如果您的脚本应该编写页面内容,则应将其放在正文部分。

【讨论】:

以上是关于在主体树中执行脚本时 DOM 准备好了吗?的主要内容,如果未能解决你的问题,请参考以下文章

页面完全加载后如何执行功能?

DBA第二批面试已经开始,您准备好了吗?

HTML Javascript - 防止从 dom 树的子节点执行脚本

iframe 中的脚本标记在父 dom 上执行

AIOps时代,你准备好了吗?

远程办公,你准备好了吗?