在页面加载完成后执行 javascript

Execute javascript after page load is complete

本文关键字:执行 javascript 加载      更新时间:2023-09-26

我有一个html页面,其中包含一些预渲染的内容和一些尚未渲染的内容。我想立即显示预呈现的内容,然后开始呈现其余内容。我没有使用jQuery

请参阅以下代码片段。我已经尝试了多种方式,包括在结束正文标签之前注入我的脚本,并提供我的脚本来填充 DOM 作为对 window.onloaddocument.body.onloaddocument.addEventListener('DOMContentLoaded') 的回调。在每种情况下,在呈现其余内容之前,页面不会显示预呈现的内容。

<html><head></head>
  <body>
    <header>What it is, my doge?</header>
    <div id="main"></div>
    <script>
      var main = document.getElementById('main');
      for (var i = 0; i < 500; i++)
        main.innerText += new Date();
    </script>
  </body>
</html>

<html><head></head>
  <body>
    <header>What it is, my doge?</header>
    <div id="main"></div>
    <script>
      var main = document.getElementById('main');
      document.body.onload = function() {
        for (var i = 0; i < 500; i++)
          main.innerText += new Date();
      };
    </script>
  </body>
</html>

<html><head></head>
      <body>
        <header>What it is, my doge?</header>
        <div id="main"></div>
        <script>
          var main = document.getElementById('main');
          window.onload = function() {
            for (var i = 0; i < 500; i++)
              main.innerText += new Date();
          };
        </script>
      </body>
    </html>

<html><head></head>
      <body>
        <header>What it is, my doge?</header>
        <div id="main"></div>
        <script>
          var main = document.getElementById('main');
          document.addEventListener('DOMContentLoaded', function() {
            for (var i = 0; i < 500; i++)
              main.innerText += new Date();
          });
        </script>
      </body>
    </html>

一种有效的情况是window.setTimeout 0 超时。但是,这只会推迟函数,直到无事可做。这是这里的最佳实践吗?

<html><head></head>
<body>
    <header>What it is, my doge?</header>
    <div id="main"></div>
    <script>
      var main = document.getElementById('main');
      window.setTimeout(function() {
        for (var i = 0; i < 500; i++)
          main.innerText += new Date();
      }, 0);
    </script>
</body>
</html>

最佳实践而言,没有。就良好常见可接受的做法而言,有少数。你已经击中了一个:

setTimeout(function() { }, 1);

在这种情况下,该函数在所有其他内联处理结束后的浏览器最小超时期限内执行。

同样,如果要确保函数在某些条件为 true 后不久运行,请使用间隔:

var readyCheck = setInterval(function() {
  if (readyCondition) {
    /* do stuff */
    clearInterval(readyCheck);
  }
}, 1);

我一直在自己的工作中使用类似但更通用的解决方案。我在标头中定义了一个辅助函数:

var upon = function(test, fn) {
    if (typeof(test) == 'function' && test()) {
        fn();
    } else if (typeof(test) == 'string' && window[test]) {
        fn();
    } else {
        setTimeout(function() { upon(test, fn); }, 50);
    }
}; // upon()

。并且在解决依赖项时触发其他功能:

upon(function() { return MyNS.Thingy; }, function() {
  //  stuff that depends on MyNS.Thingy
});
upon(function() { return document.readyState == 'complete';}, function() {
  // stuff that depends on a fully rendered document
});

或者,如果您想要更权威的良好做法,请遵循 Google 的示例。创建一个外部async脚本,并在第一个标头script之前注入它:

var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;
s.src = '/path/to/script.js';
var header_scripts = document.getElementsByTagName('script')[0];
header_scripts.parentNode.insertBefore(s, header_scripts);

从理论上讲,谷歌的解决方案适用于所有浏览器(IE <10?),以便在不干扰文档加载的情况下尽快执行外部脚本。

如果你想要一个权威的通用实践,请检查jQuery的onready解决方案的来源。

根据您的浏览器要求,您可以使用 async 标记并在内容加载后导入脚本。这可能与setTimeout(func, 0)完成相同的事情,但也许它不那么笨拙。

见 http://plnkr.co/edit/7DlNWNHnyX5s6UE8AFiU?p=preview

.html:

...
<body>
  <h1 id="main">Hello Plunker!</h1>
  <script async src="script.js"></script>
</body>
...

脚本.js:

for(var i=0; i<500; ++i) {
  document.getElementById('main').innerText += new Date();
}

我以前用过这个效果:

var everythingLoaded = setInterval(function() {
  if (/loaded|complete/.test(document.readyState)) {
    clearInterval(everythingLoaded);
    init(); // this is the function that gets called when everything is loaded
  }
}, 10);

我认为您要做的是在标签上使用onload事件。这样,在处理javascript时,首先会出现"这是什么,我的狗狗?"消息。

我还在循环中设置了超时,因此您可以更好地看到添加的行。

<html>
    <head>
        <script>
            myFunction = function() {
                for (var i = 1000; i > 0; i--) {
                    setTimeout(function() {
                        main.innerText += new Date();
                    }, 100);
                }
            };
        </script>
    </head>
    <body onload="myFunction()">
        <header>What it is, my doge?</header>
        <div id="main"></div>
    </body>
</html>