【问题标题】:Chrome: JS loads before HTMLChrome:JS 在 HTML 之前加载
【发布时间】:2018-11-05 06:56:22
【问题描述】:

我正在学习 Javascript,我很困惑为什么我在使用 Chrome 时在 html 之前加载我的 javascript 时遇到问题。当我使用 Firefox 和 Edge 时,页面首先加载 html,然后我收到警报。不过,当我使用 Chrome 时,我会先收到警报,而背景只是空白。到目前为止我学到的一切似乎都在说 js 脚本应该在 html 之后运行,因为它位于 body 标记的底部。

谢谢!

home.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>
</head>
<body>
<h1>Hi, testing chrome.</h1>
<h2>Is this working?</h2>
<ul>
<li>list1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
<script type="text/javascript" src="myjs.js"></script>
</body>
</html>

myjs.js 页面

alert("Am I working right?");

【问题讨论】:

  • 尝试在文档就绪方法中添加您的代码
  • 注意 html 确实加载了,你只是阻塞了渲染线程。从外观上看,Firefox 和 Edge 决定在显示警告框之前对到目前为止加载的 DOM 进行渲染循环,而 Chrome 则没有。这正是每个供应商决定实施其特定代码的方式。您仍然可以获取对已加载 DOM 元素的引用,例如 &lt;ul&gt;

标签: javascript html google-chrome


【解决方案1】:

如果你想让你的 html 在 js 之前先加载,请确保用

包装它
document.addEventListener("DOMContentLoaded", function(event) { 
  // your code here
});

【讨论】:

  • 嗨,我试过了,但还是一样。 document.addEventListener("DOMContentLoaded", function(event) { alert("我工作对了吗?"); });
【解决方案2】:

网络使用事件驱动模型来排序操作。您正确地假设如果脚本出现在文档的末尾,它将被解析得比它出现在开头的时间晚。但是 HTML 规范没有明确规定必须在执行脚本之前呈现 HTML。所以解析和渲染是不同的操作,chrome可能会选择在解析完成后立即执行脚本。

那么,如何正确排序您的操作?一般的网络,特别是 javascript 是事件驱动的。您的代码可以监听各种事件并随心所欲地响应它们。在这种情况下,您希望在加载文档后执行脚本。看看DOMContentLoaded 事件。

您的代码修改为在DOMContentLoaded 事件触发时运行。

document.addEventListener("DOMContentLoaded", function() {
  alert("Am I working right?");
});

我只是将您的警报函数调用包含在我的事件处理函数中。 必须在发出事件的元素上注册事件处理函数(或回调),在我们的例子中是document 对象。这是通过使用两个参数对该对象调用addEventListener() 来完成的。第一个是我们想要以字符串形式监听的事件名称,第二个是触发事件时必须执行的函数。

为许多不同的元素定义了许多事件,您甚至可以定义自己的自定义事件并响应它们。

【讨论】:

  • 感谢回复,我试过了,对于 Chrome,它仍然先加载警报,然后加载 html
  • 我刚刚试了一下,它工作正常。 Chrome 可能已在本地缓存该文件。尝试 Ctrl+Shift+r 重新加载页面,而不会影响本地缓存。
【解决方案3】:

由于 JavaScript 是单线程的,所以当你调用 alert() 函数时,它会阻塞其他执行,因为它是一个 UI 阻塞函数。

【讨论】:

    【解决方案4】:

    将代码放在Jquery文档就绪方法中

    【讨论】:

    • 为什么?可以看到 jQuery 没有加载到页面中。
    【解决方案5】:

    DOMContentLoaded 函数让浏览器在 HTML 内容加载后执行一段 javascript 代码

      document.addEventListener("DOMContentLoaded", function(event) { 
        /*it is verry easy now, you can write code here which will be executed when the 
         html content will end loading*/
      });
    

    【讨论】:

      【解决方案6】:

      您应该始终在 JS 文件中做的事情是将每个直接代码和与 DOM 相关的函数放在一个函数中等待页面加载。

      在纯 JavaScript 中:

      window.onload = function() {
          //Your JS here
      };
      

      注意,根据this post,可以使用document.onload(function() {...});

      使用 JQuery :

      $(function() {
          //Your JS here
      });
      

      【讨论】:

      • 请注意,因为他们的代码位于页面底部,所以上面的所有 DOM 元素都已加载。在这种情况下,如果您的目标是等待元素存在,则无需将其放入加载事件中
      • 是的。但是在使用外部 JS 文件时,检查页面是否加载总是好的。通常,应始终检查输入。
      • 当我尝试将其放入 window.onload(function() { ...});我收到一个错误,说 window.onload 不是函数
      • 哎呀! window.onload = function() {...}; 而不是 window.onload(function() {...}); 正在修复。
      • 非常感谢!我仍然不确定它为什么会起作用,但我会查找它。这是我应该始终将其视为“良好做法”的事情吗?
      【解决方案7】:

      在纯 JavaScript 中,在 myjs.js 中试试这个

      $(window).on("load", function(){
          var ss = document.createElement("script");
          ss.src = "myjs.js";
          ss.type = "text/javascript";
          document.getElementsByTagName("head")[0].appendChild(ss);
      });
      

      否则

      如果加载了 jQuery,试试这个。

      $(function() {
          alert("Am I wrong?");
      });
      

      你需要添加

      <script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js">
      

      在标签中包含jQuery

      这应该确保页面已加载。但请注意 标签也是 DOM 的一部分

      如果需要加载HTML后执行外部JS,可以试试这个。

      $(function() {
          var ss = document.createElement("script");
          ss.src = "myjs.js";
          ss.type = "text/javascript";
          document.getElementsByTagName("head")[0].appendChild(ss);
      });
      

      【讨论】:

      • 您能否解释一下这将如何解决 OP 的问题? IIFE 不会改变任何重要的事情。
      • 这不会确保页面首先加载,您使用的是 IIFE,顾名思义,它会立即执行您不会更改执行时间。你可能会混淆 IIFE 和 jQuery 的 $(function(){}) 的外观,这是 jQuery 对 $(document).ready(function(){}) 的简写
      • @Teemu - 我已经编辑了代码 sn-p。第二个 sn-p:匿名函数在文档加载后执行,然后它创建一个脚本元素并将其作为子元素附加到 head 元素。如果您需要更多解释,请告诉我
      • @PatrickEvans - 我已经编辑了代码,错过了自调用函数中的 jQuery 参数。是的,重点是确保文档已加载。顺便说一句,有不同的方法。 sitepoint.com/types-document-ready
      • 您仍然只是在使用 IIFE,您的所有代码所做的只是将 jQuery 作为参数传递,也从未实际使用过它。如果你想使用 jQuery 的 dom 就绪事件,它必须是 jQuery(function(){})$(function(){})。您获得 (function(){})(jQuery) 的页面上的代码用于当您可能加载多个 jQuery 实例时,它与实际的 dom 准备情况无关
      猜你喜欢
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多