【问题标题】:placing <script> tags right before </body> doesn't work as expected在 </body> 之前放置 <script> 标签不能按预期工作
【发布时间】:2018-08-16 11:07:05
【问题描述】:

我正在看一个教程,其中导师建议为了改善用户体验最好在 &lt;/body&gt; 之前添加 &lt;script&gt; 标签,以便脚本在页面内容完全加载后运行。

我尝试了这段代码,我希望看到“hello world!”在任何脚本运行之前,但我的浏览器在其他所有内容出现之前运行 javascript(仅显示带有警报框的空白页面)

<html>
 <body>

  <p>hello world!</p>

  <script>
   alert('hey there');
  </script>

 </body>
</html>

我用 safari/chrome/opera 尝试了这个,得到了相同的结果。我知道我可以使用 jQuery 来解决这个问题,但有人可以解释一下这种行为吗?


感谢@T.J.Crowder,我标记了正确答案,以防万一有人对幕后发生的事情感到好奇,我在这里找到了一个很好的解释: Script is before /body but it runs before page is loaded

【问题讨论】:

  • 我猜“页面内容已完全加载”是夸大其词。它没有完全加载,它只是被解释并且元素存在在那里供你使用,但并不意味着它被渲染了。
  • stackoverflow.com/questions/807878/… 查看此链接。它回答了你的问题。
  • 大多数现代浏览器会等到脚本完成后再渲染页面。
  • @sodali_ayran - 这是在问一个不同的问题,虽然那里的大多数解决方案都可以工作(因为他们提出了一个糟糕的反模式,使用窗口 load 事件),但它不是关闭的好选择这个问题。

标签: javascript html dom


【解决方案1】:

...所以脚本在页面内容完全加载后运行。

正确,它上面的所有元素都被解析并在 DOM 中——但是,浏览器可能还没有机会渲染它们。给它一个这样做的机会,通过对您的代码进行非常小的延迟。

    <script>
    setTimeout(function() {
        alert('hey there');
    }, 50);
    </script>
</body>

现场示例:

<p>hello world!</p>
<script>
setTimeout(function() {
    alert('hey there');
}, 50);
</script>

这增加了 50 毫秒的延迟——人类不会注意到任何事情。但如果你想要绝对最小延迟:

    <script>
    requestAnimationFrame(function() {
        setTimeout(function() {
            alert('hey there');
        }, 0);
    });
    </script>
</body>

现场示例:

<p>hello world!</p>
<script>
requestAnimationFrame(function() {
    setTimeout(function() {
        alert('hey there');
    }, 0);
});
</script>

更多:

不过,那些不会等待所有图像等加载。如果您想等待一切(可能需要很长时间),请使用window load event,查看该链接或this answer 以获取示例。

【讨论】:

    【解决方案2】:

    当一个 script 标签放在 body 标签的底部时,它仅仅意味着在脚本运行之前处理了 DOM 的其余部分。它不保证页面已完全呈现。

    您可以使用load 事件来确保页面已呈现:

    <html>
     <body>
    
      <p>hello world!</p>
    
      <script>
       alert('hey there');
       
       window.onload = function() {
          alert("Page has rendered");
       };
      </script>
    
     </body>
    </html>

    【讨论】:

    • load 发生在页面加载过程的非常后期,在所有内容(包括所有图像)都已加载之后。这通常不是您想要的(尽管在这种特定情况下可能是这样)。
    【解决方案3】:

    你可以使用

    document.addEventListener("DOMContentLoaded", function() {
      alert('hey there');
    });
    

    它是 jquery document ready 的原版 js 等价物

    编辑:与 Nisarg Shah 回答中的窗口加载的主要区别在于,这不会等到网站完全加载(外部样式、图像等)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 2013-05-28
    • 1970-01-01
    相关资源
    最近更新 更多