页面加载后如何使JavaScript执行?


736

我正在使用<script>inside 执行外部脚本<head>

现在,由于脚本是页面加载之前执行的,因此我无法访问<body>。在文档“加载”后(HTML已完全下载并在RAM中),我想执行一些JavaScript。执行脚本时,是否有任何我可以挂上的事件会在页面加载时触发?

Answers:


835

这些解决方案将起作用:

<body onload="script();">

要么

document.onload = function ...

甚至

window.onload = function ...

请注意,最后一个选项是更好的选择,因为它不引人注目并且被认为是更标准的


5
<body onload =“ script();”>和document.onload = function ...有什么区别?
Mentoliptus

11
@mentoliptus:document.onload=是非侵入性的 en.wikipedia.org/wiki/Unobtrusive_JavaScript
marcgg 2011年

3
html中的脚本...否否否$(function(){代码在此处}); <

21
@gerdi OP没有提及有关jQuery的任何内容。我在回答中也给出了一个不引人注目的选项。
marcgg 2014年

1
document.onload对我不起作用。我发现此帖子带有相同的问题stackoverflow.com/questions/5135638/…。似乎不是document.onload是一个选项。
spottedmahn

196

使脚本设置在加载时运行的函数的合理可移植,非框架的方式:

if(window.attachEvent) {
    window.attachEvent('onload', yourFunctionName);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            yourFunctionName(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = yourFunctionName;
    }
}

10
+1几乎完全符合我6个月前的想法。如果您无法控制的其他框架和代码正在添加onload事件,并且您也希望不清除其他onload事件,则这样的代码可能是必需的。我将实现作为函数包含在内,并且需要var newonload = function(evt){curronload(evt); newOnload(evt); },因为某种原因,我使用的框架要求将一个事件传递给onload事件。
Grant Wagner,2009年

6
我只是在测试中发现,编写的代码导致在附加attachEvent()时以不确定的顺序触发处理程序。如果处理程序的执行顺序很重要,则可能要忽略window.attachEvent分支。
格兰特·瓦格纳

因此,这会将此功能添加为附加功能以运行OnLoad,对吗?(而不是替换现有的onload事件)
Clay Nichols

@ClayNichols:正确。
混乱

2
好的解决方案,但现在已经过时了:developer.mozilla.org/en-US/docs/Web/API/EventTarget/…–
Renan

192

请记住,加载页面有多个阶段。顺便说一句,这是纯JavaScript

“ DOMContentLoaded”

初始HTML文档已完全加载和解析而没有等待样式表,图像和子帧完成加载时,将引发此事件。在此阶段,您可以根据用户设备或带宽速度以编程方式优化图像和CSS的加载。

在加载DOM之后执行(在img和css之前):

document.addEventListener("DOMContentLoaded", function(){
    //....
});

注意:同步JavaScript会暂停DOM的解析。如果您希望在用户请求页面后尽快解析DOM,则可以将JavaScript异步化优化样式表的加载

“加载”

完全不同的事件load只能用于检测已满的页面。在DOMContentLoaded更合适的地方使用负载是一个非常普遍的错误,因此请务必谨慎。

加载并解析所有内容后的摘录:

window.addEventListener("load", function(){
    // ....
});

MDN资源:

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load

所有事件的MDN列表:

https://developer.mozilla.org/zh-CN/docs/Web/Events


1
@Peter可以肯定,如果将它放在您的javascript文件的底部,则最好单独使用,这样它才能最后执行
arodebaugh

Javascript将DOM的渲染暂停在那里,最好的方法是将其放在页面底部或将JavaScript异步加载到标头中。
DevWL

这是最完整的答案。onload之后,但人们最初并没有意识到这一点。
tfont

1
重新异步javascript:澄清一下,有两种选择可以立即运行,而无需立即运行。其中,延迟通常比异步更可取-因为延迟不会中断html解析/渲染-并且在运行时,可以保证DOM已经准备就绪。通过defer和async有效地加载JavaScript
ToolmakerSteve

+1我试着window.onload = ...以为我的脚本会等到所有内容都完全下载后再运行,但window.onload实际上它的行为类似于document.addEventListener("DOMContentLoaded", ...,而window.addEventListener("load", ...实际上确实等待所有内容都被完全下载。我本以为window.onload应该等于window.addEventListener("load", ...而不是document.addEventListener("DOMContentLoaded", ...?? 我在Chrome和FF中得到了相同的结果。
wkille

121

您可以在体内放置“ onload”属性

...<body onload="myFunction()">...

或者,如果您使用的是jQuery,则可以

$(document).ready(function(){ /*code here*/ }) 

or 

$(window).load(function(){ /*code here*/ })

希望它能回答您的问题。

请注意,$(window).load将在页面上呈现文档后执行。


65

如果脚本加载在<head>文档的内,则可以使用deferscript标签中的属性。

例:

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

来自https://developer.mozilla.org

推迟

设置此布尔值属性是为了向浏览器指示脚本应在解析文档之后但在触发DOMContentLoaded之前执行。

如果不存在src属性(即,对于内联脚本),则不得使用此属性,在这种情况下,它将无效。

要对动态插入的脚本实现类似的效果,请改用async = false。具有defer属性的脚本将按照它们在文档中出现的顺序执行。


我喜欢这个解决方案,因为不需要任何JavaScript代码,而只需要一个html属性<3
sarkiroka

27

这是一个基于页面加载后延迟js加载的脚本,

<script type="text/javascript">
  function downloadJSAtOnload() {
      var element = document.createElement("script");
      element.src = "deferredfunctions.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>

我该放在哪里?

将代码粘贴到HTML中的</body>标记之前(HTML文件底部附近)。

它有什么作用?

该代码表示​​等待整个文档加载,然后加载外部文件deferredfunctions.js

这是上述代码的示例-JS的延迟渲染

我基于延迟加载javascript pagespeed google概念而编写了此文件,也从本文中获得了延迟加载javascript的信息




10
<script type="text/javascript">
  function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "defer.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>

http://www.feedthebot.com/pagespeed/defer-loading-javascript.html




7

我有时发现在更复杂的页面上,在window.onload被触发时,并非所有元素都已加载。如果是这种情况,请在函数延迟之前添加setTimeout。它不是很优雅,但是可以很好地渲染它。

window.onload = function(){ doSomethingCool(); };

变成...

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };

5

只需定义<body onload="aFunction()">在页面加载后将调用的方法即可。然后,脚本中的代码将用括起来aFunction() { }



3

使用YUI库(我喜欢它):

YAHOO.util.Event.onDOMReady(function(){
    //your code
});

便携美观!但是,如果您不将YUI用于其他内容(请参阅其文档),我会说不值得使用它。

注意:要使用此代码,您需要导入2个脚本

<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>

3

关于如何检测使用Javascript或Jquery 加载文档的文档非常不错。

使用本机Javascript可以实现

if (document.readyState === "complete") {
 init();
 }

这也可以在间隔内完成

var interval = setInterval(function() {
    if(document.readyState === 'complete') {
        clearInterval(interval);
        init();
    }    
}, 100);

例如,Mozilla

switch (document.readyState) {
  case "loading":
    // The document is still loading.
    break;
  case "interactive":
    // The document has finished loading. We can now access the DOM elements.
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // The page is fully loaded.
    console.log("Page is loaded completely");
    break;
}

使用Jquery仅检查DOM是否准备就绪

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

要检查是否所有资源都已加载,请使用window.load

 $( window ).load(function() {
        console.log( "window loaded" );
    });


3
$(window).on("load", function(){ ... });

.ready()最适合我。

$(document).ready(function(){ ... });

.load()可以使用,但是不会等到页面加载完毕。

jQuery(window).load(function () { ... });

对我不起作用,中断了下一个内联脚本。我还使用jQuery 3.2.1以及其他一些jQuery分支。

要隐藏我的网站加载叠加层,我使用以下方法:

<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>

3

的JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

与jQuery相同:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});





注意: -不要使用下面的标记(因为它会覆盖其他相同类型的声明):

document.onreadystatechange = ...

1

正如Daniel所说,您可以使用document.onload。

但是,各种JavaScript框架(jQuery,Mootools等)都使用自定义事件“ domready”,我想它必须更有效。如果您使用javascript开发,强烈建议您使用框架,它们可以极大地提高您的生产率。


1

<script type="text/javascript">
$(window).bind("load", function() { 

// your javascript event here

});
</script>


4
这个答案取决于jquery
Chiptus

0

asnyc脚本标记的我的advice使用属性可以帮助您在页面加载后加载外部脚本

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>

7
根据w3schools的介绍如果存在异步:脚本与页面的其余部分异步执行(脚本将在页面继续解析时执行)。也许您是说defer像@Daniel Price提到的那样?
jk7 2015年

0

使用自我执行onload函数

window.onload = function (){
    /* statements */
}();   

2
您可以onload使用此方法覆盖其他处理程序。相反,您应该添加侦听器。
Leonid Dashko '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.