页面加载完成后执行javascript [重复]

Posted

技术标签:

【中文标题】页面加载完成后执行javascript [重复]【英文标题】:Execute javascript after page load is complete [duplicate] 【发布时间】:2015-01-13 07:05:10 【问题描述】:

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

参见下面的 sn-p。我尝试了各种方法,包括在结束正文标记之前注入我的脚本,并提供我的脚本来填充 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>

【问题讨论】:

1) 我们需要这里的代码。 2)您的描述与小提琴不符。 3) window.onload 将在所有内容加载完毕后触发。你需要做的就是把你的电话放在&lt;/body&gt;标签之前 小提琴正是你所描述的一个例子,它显然不起作用。 @MatthewJamesDavis 您的未渲染内容是如何渲染的? 任意。可能通过剔除或通过 DOM API 附加文档片段。 注意:setTimeout(function(), 0) 方法在 FireFox 中似乎不起作用。它需要约 50-100 毫秒的超时时间。 【参考方案1】:

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

setTimeout(function()  , 1);

在这种情况下,函数在所有其他内联处理结束后在the browser's minimum timeout period 内执行。

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

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);

Google 的解决方案理论上适用于所有浏览器(IE

如果您想要一个权威的common实践,请查看 jQuery 的onready 解决方案的来源。

【讨论】:

知道为什么谷歌建议你建议你注入它而不是包含它吗? @MatthewJamesDavis Two reasons 我知道。这里似乎只有一个相关:某些浏览器不支持async 属性。 @MatthewJamesDavis 在此处查看对async 的浏览器支持:developer.mozilla.org/en-US/docs/Web/HTML/Element/… 我会在你对未来求职者的回答中包含异步 @svidgen:我可以直接使用带有 aync 属性的标题部分中的脚本标记来代替脚本注入吗? (如下所示)&lt;script async src="/path/to/script.js" type="text/javascript"&gt;&lt;/script&gt;【参考方案2】:

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

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

html:

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

script.js:

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

【讨论】:

它的 hacky 少了很多。 setTimeout 方法说“嘿,在你下载这个脚本时停止一切,然后完成你要做的任何事情,然后执行脚本”,其中 async 说“完成所有事情,然后在准备好时执行脚本”【参考方案3】:

我以前用过这个效果:

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);

【讨论】:

【参考方案4】:

我认为您想要做的是在标签上使用 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>

【讨论】:

欣赏答案。然而,这并不像我发布的想法那样最佳,在回调之外设置一个对 window.setTimeout 的调用,超时为 0,这要快得多。

以上是关于页面加载完成后执行javascript [重复]的主要内容,如果未能解决你的问题,请参考以下文章

页面用jquery的load()方法加载新页面之后怎么返回上一页

加载页面后运行javascript [重复]

页面完全呈现后运行 javascript

如何让js在页面加载后只执行一次,也就是再次刷新当前页,不再执行js

使用 ajax 分页加载页面后重新初始化其他 javascript 函数

页面加载后如何立即调用javascript方法[重复]