【问题标题】:Load HTML first before Javascript在 Javascript 之前先加载 HTML
【发布时间】: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)了。也就是说,你能告诉我怎么做吗?
  • @Capricorn - 我尝试按照链接上的内容进行操作,但它对我不起作用。也许我做错了?
  • 你能告诉我们你的浏览器控制台吗,只需按 F12 并选择控制台选项卡。如果那里记录了错误,那可能会有所帮助。

标签: javascript html node.js socket.io


【解决方案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 不是更好吗?
    • 我没有尝试过,这种方法在我的页面上非常有效。会试试的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多