934

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

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

4

26 回答 26

1053

这些解决方案将起作用:

如评论中所述,使用defer

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

或者

<body onload="script();">

或者

document.onload = function ...

甚至

window.onload = function ...

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

于 2009-04-30T16:41:16.300 回答
361

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

“DOMContentLoaded”

初始 HTML 文档已完全加载和解析时触发此事件,无需等待样式表、图像和子框架完成加载。在这个阶段,您可以根据用户设备或带宽速度以编程方式优化图像和 CSS 的加载。

在加载 DOM 之后执行(在图像和 CSS 之前):

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

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

“加载”

一个非常不同的事件load应该只用于检测完全加载的页面。在 DOMContentLoaded 更合适的地方使用 load 是一个非常普遍的错误,所以要小心。

在加载和解析所有内容后执行:

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/en-US/docs/Web/Events

于 2016-03-19T00:50:30.190 回答
207

让您的脚本设置一个在加载时运行的函数的合理可移植、非框架方式:

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;
    }
}
于 2009-04-30T16:59:58.797 回答
135

您可以在正文中放置一个“onload”属性

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

或者,如果您使用的是 jQuery,您可以这样做

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

or 

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

我希望它能回答你的问题。

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

于 2009-04-30T16:42:29.370 回答
78

如果脚本是在<head>文档中加载的,那么可以使用defer脚本标签中的属性。

例子:

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

来自https://developer.mozilla.org

推迟

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

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

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

于 2014-01-10T08:52:41.803 回答
33

这是一个基于页面加载后延迟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 概念编写了这篇文章,也来自这篇文章Defer loading javascript

于 2013-02-05T12:40:15.160 回答
22

查看 hookingdocument.onload或 jQuery $(document).load(...)

于 2009-04-30T16:40:17.847 回答
22

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 = ...
于 2020-04-06T16:22:49.237 回答
11

工作小提琴<body onload="myFunction()">

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
   function myFunction(){
    alert("Page is loaded");
   }
  </script>
 </head>

 <body onload="myFunction()">
  <h1>Hello World!</h1>
 </body>    
</html>
于 2013-03-26T09:39:35.327 回答
11
<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

于 2014-09-11T19:23:34.707 回答
9

如果您使用的是 jQuery,

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

相当于

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

或另一种简写:

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

请参阅JQuery $function() 触发什么事件?https://api.jquery.com/ready/

于 2013-03-06T20:39:46.337 回答
9

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

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

变成……

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
于 2013-07-20T21:13:54.907 回答
7
document.onreadystatechange = function(){
     if(document.readyState === 'complete'){
         /*code here*/
     }
}

看这里: http: //msdn.microsoft.com/en-us/library/ie/ms536957 (v=vs.85).aspx

于 2014-09-11T11:41:40.550 回答
6

只需定义<body onload="aFunction()">将在页面加载后调用。您在脚本中的代码不是由aFunction() { }.

于 2009-04-30T16:41:05.957 回答
4
<body onload="myFunction()">

这段代码运行良好。

但是window.onload方法有各种依赖关系。所以它可能不会一直有效。

于 2013-04-29T11:32:29.427 回答
4

比较

在下面的片段中,我收集了选择的方法并显示了它们的顺序。评论

  • 任何现代document.onload浏览器都不支持 (X) (从不触发事件)
  • 如果您<body onload="bodyOnLoad()">同时使用 (F) 和window.onload(E),那么只会执行第一个(因为它会覆盖第二个)
  • (F) 中给出的事件处理程序<body onload="...">由附加onload函数包装
  • document.onreadystatechange(D) 不覆盖document .addEventListener('readystatechange'...)(C) 可能 cecasueonXYZevent-like方法独立于addEventListener队列(允许添加多个侦听器)。执行这两个处理程序之间可能没有任何反应。
  • 所有脚本都在控制台中写入其时间戳 - 但也div可以在正文中写入其时间戳的脚本(在脚本执行后单击“整页”链接以查看它)。
  • 解决方案readystatechange(C,D)由浏览器多次执行,但针对不同的文档状态:
    • loading - 文档正在加载(没有在代码段中触发)
    • 交互式- 文档被解析,之前触发DOMContentLoaded
    • 完成- 文档和资源已加载,之前触发body/window onload

<html>

<head>
  <script>
    // solution A
    console.log(`[timestamp: ${Date.now()}] A: Head script`);
    
    // solution B
    document.addEventListener("DOMContentLoaded", () => {
      print(`[timestamp: ${Date.now()}] B: DOMContentLoaded`);
    });

    // solution C
    document.addEventListener('readystatechange', () => {
      print(`[timestamp: ${Date.now()}] C: ReadyState: ${document.readyState}`);
    });
   
    // solution D
    document.onreadystatechange = s=> {print(`[timestamp: ${Date.now()}] D: document.onreadystatechange ReadyState: ${document.readyState}`)};
    
    // solution E (never executed)
    window.onload = () => {
      print(`E: <body onload="..."> override this handler`);
    };

    // solution F
    function bodyOnLoad() {
      print(`[timestamp: ${Date.now()}] F: <body onload='...'>`);      
      infoAboutOnLoad(); // additional info
    }
    
    // solution X
    document.onload = () => {print(`document.onload is never fired`)};



    // HELPERS

    function print(txt) { 
      console.log(txt);
      if(mydiv) mydiv.innerHTML += txt.replace('<','&lt;').replace('>','&gt;') + '<br>';
    }
    
    function infoAboutOnLoad() {
      console.log("window.onload (after  override):", (''+document.body.onload).replace(/\s+/g,' '));
      console.log(`body.onload==window.onload --> ${document.body.onload==window.onload}`);
    }
            
    console.log("window.onload (before override):", (''+document.body.onload).replace(/\s+/g,' '));

  </script>
</head>

<body onload="bodyOnLoad()">
  <div id="mydiv"></div>

  <!-- this script must te at the bottom of <body> -->
  <script>
    // solution G
    print(`[timestamp: ${Date.now()}] G: <body> bottom script`);
  </script>
</body>

</html>

于 2020-06-17T17:59:38.047 回答
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" );
    });
于 2015-12-12T08:42:00.907 回答
3

将此代码与 jQuery 库一起使用,这将非常好。

$(window).bind("load", function() { 

  // your javascript event

});
于 2017-12-21T13:32:26.847 回答
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>
于 2018-03-08T02:42:57.043 回答
2

您可以在特定脚本文件上编写一个函数,并使用 onload 属性将其调用到您的 body 元素中。

示例:

<script>
  afterPageLoad() {
   //your code here
}
</script>

现在使用 script 标签将您的脚本调用到您的 html 页面中:

<script src="afterload.js"></script>

进入你的身体元素;像这样添加 onload 属性:

<body onload="afterPageLoad();">
于 2021-04-02T08:16:11.947 回答
2

DOMContentLoaded 事件在初始 HTML 文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载。

document.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
});

加载整个页面时会触发 load 事件,包括所有相关资源,例如样式表和图像。这与 DOMContentLoaded 不同,后者在页面 DOM 加载后立即触发,无需等待资源完成加载。

window.addEventListener('load', (event) => {
  console.log('page is fully loaded');
});

于 2021-11-15T07:31:25.457 回答
1

正如丹尼尔所说,您可以使用 document.onload。

各种 javascript 框架(jQuery、Mootools 等)都使用自定义事件“domready”,我想这一定更有效。如果您使用 javascript 进行开发,我强烈建议您使用框架,它们会大大提高您的工作效率。

于 2009-04-30T16:47:28.233 回答
1

使用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>
于 2009-04-30T17:36:51.377 回答
0

我建议使用asnyc脚本标签的属性,这可以帮助您在页面加载后加载外部脚本

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>
于 2015-03-30T05:43:37.123 回答
0

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

// your javascript event here

});
</script>

于 2015-09-29T08:43:45.973 回答
0

我可以通过此代码捕获页面加载

<script>
console.log("logger saber");

window.onload = (event) => {
  console.log('page is fully loaded');
document.getElementById("tafahomNameId_78ec7c44-beab-40de-9326-095f474519f4_$LookupField").value = 1;;
};

</script>
于 2021-03-30T10:43:53.977 回答