在 Javascript 之前先加载 HTML

Posted

技术标签:

【中文标题】在 Javascript 之前先加载 HTML【英文标题】:Load HTML first before Javascript 【发布时间】:2018-12-20 09:35:34 【问题描述】:

我正在尝试实时开发一些东西,在这种情况下,我将 socketio 用于 nodejs。尽管其他一切工作正常,但我现在的主要问题是我的程序在 html 之前首先加载了 javascript,因此这意味着开始时的输出只是空的。

在我的代码中,javascript 调用数据库中的所有其他内容,并通过标签连接起来,然后在 html 中抛出。

这是我的 html 代码:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <table>
    <tr>
      <td>
        <table id="output" border=1>
          <thead id="headers">
            <th>Name</th>
            <th>Address</th>
            <th>Number</th>
          </thead>
          <tbody id="online">
          </tbody>
        </table>
      </td>
      <td>
        <table id="output" border=1>
          <thead id="headers">
            <th>Name</th>
            <th>Address</th>
            <th>Number</th>
          </thead>
          <tbody id="offline">
          </tbody>
        </table>
      </td>
    </tr>
  </table>
  <script src="/chat.js"></script>
</body>
</html>

这里是javascript:

var online = document.getElementById('online'),
  offline = document.getElementById('offline');

socket.on('user joined', function(data) 
  online.innerHTML = "";
  for (var ctr = 0; ctr < data.length; ctr++) 
    online.innerHTML += '<td>' + data[ctr].name + '</td>' +
      '<td>' + data[ctr].address + '</td>' +
      '<td>' + data[ctr].number + '</td>';
  
);

socket.on('user left', function(data) 
  offline.innerHTML = "";
  for (var ctr = 0; ctr < data.length; ctr++) 
    offline.innerHTML += '<td>' + data[ctr].name + '</td>' +
      '<td>' + data[ctr].address + '</td>' +
      '<td>' + data[ctr].number + '</td>';
  
);

我已经在网上搜索过这个,但是我的情况不同,因为我在 html 中调用 javascript 文件,而不是让所有脚本都带有 html 本身。

我也读过在 html 工作之后调用 javascript 文件,但显然,我已经做到了(如我的代码中所见),但仍然没有。

【问题讨论】:

你可以让脚本只在正文加载后执行吗?这将适用于您的用例 我理解这就是我想要实现的目标,但是我对与前端的几乎任何关系都不太熟悉,更不用说 html(甚至 css)了。也就是说,你能告诉我怎么做吗? 看到这个问题:***.com/questions/807878/… @Capricorn - 我尝试按照链接上的内容进行操作,但它对我不起作用。也许我做错了? 你能告诉我们你的浏览器控制台吗,只需按 F12 并选择控制台选项卡。如果那里记录了错误,那可能会有所帮助。 【参考方案1】:

你可以使用DOMContentLoaded:

当初始 HTML 文档完全加载和解析时触发 DOMContentLoaded 事件,无需等待样式表、图像和子框架完成加载。一个非常不同的事件加载应该只用于检测一个完全加载的页面。在 DOMContentLoaded 更合适的地方使用 load 是一个非常常见的错误,所以要小心。

用以下代码包装您的 JavaScript 代码:

document.addEventListener("DOMContentLoaded", function(event)  
  // your code here
);

【讨论】:

有人请解释为什么这个答案会被否决,这似乎对我有用,只是缺乏一些解释。 当初始 HTML 文档完全加载和解析时触发 DOMContentLoaded 事件,无需等待样式表、图像和子框架完成加载。一个非常不同的事件加载应该只用于检测一个完全加载的页面。在 DOMContentLoaded 更合适的地方使用 load 是一个非常常见的错误,所以要小心。更多关于 - developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded 很抱歉,谁能告诉我如何将它与我提供的代码结合起来?我试过了,但它对我不起作用。我想我做错了。【参考方案2】:

这可能有效:

<body onload="script();">

document.onload = function ...

甚至

window.onload = function ...

复制自JavaScript that executes after page load

【讨论】:

对我不起作用。如果我按 F12 并转到控制台选项卡,它会显示“它说,脚本未定义”【参考方案3】:

按照 Manums 的回答,您可以使用 DOMContentLoaded:

包装您的代码

当初始 HTML 文档完全加载和解析时触发 DOMContentLoaded 事件,无需等待样式表、图像和子框架完成加载。一个非常不同的事件加载应该只用于检测一个完全加载的页面。在 DOMContentLoaded 更合适的地方使用 load 是一个非常常见的错误,所以要小心。更多关于 DOMContentLoaded - here

这里是一段代码sn-p,等待页面加载,然后打开chat.js文件。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <table>
    <tr>
      <td>
        <table id="output" border=1>
          <thead id="headers">
            <th>Name</th>
            <th>Address</th>
            <th>Number</th>
          </thead>
          <tbody id="online">
          </tbody>
        </table>
      </td>
      <td>
        <table id="output" border=1>
          <thead id="headers">
            <th>Name</th>
            <th>Address</th>
            <th>Number</th>
          </thead>
          <tbody id="offline">
          </tbody>
        </table>
      </td>
    </tr>
  </table>
  <script type="text/javascript">
  function downloadJSAtOnload() 
      var element = document.createElement("script");
      element.src = "/chat.js";
      document.body.appendChild(element);
  

  if (window.addEventListener)
      window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>
</body>
</html>

更新:您可以在 head tag 中加载脚本并使用 defer 属性

<script src="/chat.js" defer></script>

推迟

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

如果 src 属性不存在(即 对于内联脚本),在这种情况下它不会有任何效果。

要为动态插入的脚本实现类似的效果,请使用 async=false 代替。具有 defer 属性的脚本将在 它们在文档中出现的顺序。

关注here的回答

【讨论】:

感谢您为回答我的问题所做的努力,但仍然无法正常工作。有什么替代品可以用吗? @DayIsGreen 你试过直接在html文件中输入脚本吗? 是的,虽然它有效,但我更喜欢这样做(在我上面的代码中),因为当我将它直接放入 html 文件时遇到问题,例如旧记录与新记录连接,但这是一个不同的问题,所以我希望坚持我已经做过的事情。 @DayIsGreen 另一种选择可能是使用 onload 函数 function myFunction() //code here to load your script &lt;body onload = myFunction()&gt; 或类似的东西 在按 F12 时,根据控制台选项卡,这似乎不会产生任何类型的错误,但它仍然不起作用。我非常确定每次加载页面时都会在加载时发送数据。【参考方案4】:

我找到了问题的答案。 看来这不是 html 问题也不是 javascript 问题,而是 socketio 问题。

我使用的是“socket.broadcast.emit”,而不是“io.sockets.emit”

【讨论】:

【参考方案5】:

这是一个常见问题,可以通过将 JavaScript 代码封装在内部轻松解决

window.setTimeout(function() 

// your js code goes here

, 500);

【讨论】:

不知道这是否是正确的解决方案 - 使用一些 dom-loading-events 不是更好吗? 我没有尝试过,这种方法在我的页面上非常有效。会试试的。

以上是关于在 Javascript 之前先加载 HTML的主要内容,如果未能解决你的问题,请参考以下文章

tableView在加载数据成功之前先展示了footerView-医生工作台1期

在页面加载前先出现加载loading,页面加载完成之后再显示页面

如何将数据表导出到 xls,在导出前先询问密码

图片的预加载之无序加载

核心数据:何时何地首先加载实体?

经典干货JAVA面试精选之Java算法与编程 | 超详细的代码解析