在页面完全加载后执行函数

174

我正在使用以下代码在页面加载后执行一些语句。

 <script type="text/javascript">
    window.onload = function () { 

        newInvite();
        document.ag.src="b.jpg";
    }
</script>

但是这段代码不起作用。即使有些图像或元素正在加载,该函数仍然被调用。我想要的是在页面完全加载后调用该函数。


1
你能在 http://JSFiddle.net 上添加一个演示吗? - Some Guy
2
你能使用jQuery吗?如果可以的话,请尝试使用$(window).load() - Matt Hintzke
1
是的,您能解释一下哪里出了问题吗?您是否遇到了错误,或者可能在窗口重新绘制之前调用了“alert”函数(使其看起来像在加载之前调用)?代码看起来很好,强制用户下载大型库可能无法解决此问题,也不会使诊断变得更容易。 - Jeffrey Sweeney
1
你如何确定图片没有加载?我通常通过检查图片的 width 是否大于0来进行测试。 - Jeffrey Sweeney
1
这个回答解决了你的问题吗?如何让JavaScript在页面加载后执行? - T.Todua
显示剩余5条评论
16个回答

212

这可能适合您:

document.addEventListener('DOMContentLoaded', function() {
   // your code here
}, false);

或者,如果您熟悉jQuery的话,

$(document).ready(function(){
// your code
});

$(document).ready()会在DOMContentLoaded事件中触发,但是这个事件在不同的浏览器中并不一致。因此,jQuery很可能会实现一些重型解决方案来支持所有浏览器。这将使使用纯JavaScript“精确”模拟这种行为变得非常困难(但当然不是不可能)。

正如Jeffrey Sweeney和J Torres所建议的那样,我认为最好在触发函数之前使用setTimeout函数,如下所示:

setTimeout(function(){
 //your code here
}, 3000);

17
jQuery的ready不会实现OP所请求的功能。ready事件会在DOM加载完成后触发,而非元素加载完成后。要想在元素加载完成/渲染完成后触发事件,需使用load事件。 - Jaime Torres
3
@shreedhar或者他可以使用正确的工具来完成工作(load)。 - Jaime Torres
22
setTimeout 是个不好的选择。它依赖于页面在3秒内(或根据你选择的值可能是n秒)加载完成。如果加载时间更长,它就无法工作;如果页面加载得更快,它也需要无意义地等待。 - JJJ
2
@ChristianMatthew它的useCapture。如果为true,则useCapture表示用户希望启动捕获。在启动捕获后,所有指定类型的事件将首先分派到注册的侦听器,然后再分派到DOM树中其下方的任何EventTargets。通过树向上冒泡的事件不会触发指定使用捕获的侦听器。有关详细说明,请参见DOM Level 3 Events - Shreedhar
1
这怎么可能是第一答案?DOMContentLoaded事件将比window.onload事件更早触发... - Ryan Walker
显示剩余6条评论

97

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 = ...

2
这是否具有跨浏览器支持? - B''H Bi'ezras -- Boruch Hashem
1
是的,它是https://caniuse.com/mdn-api_document_readystate - Alan Delval
不管是删除你的回答还是删除另一个重复的回答,都不要将其变成链接来破坏它。 - Martijn Pieters
event.target.readyState === "complete"非常有用,谢谢!我认为这应该是正确的答案,而不是排名最高的答案。 - Teddy van Jerry
比顶部答案好得多的解决方案 - Bigbob23

49

我有点困惑,你所说的页面加载完成是指"DOM加载"还是"内容加载"?在一个HTML页面中,加载可以在两种类型的事件后触发。

  1. DOM load: Which ensure the entire DOM tree loaded start to end. But not ensure load the reference content. Suppose you added images by the img tags, so this event ensure that all the img loaded but no the images properly loaded or not. To get this event you should write following way:

    document.addEventListener('DOMContentLoaded', function() {
       // your code here
    }, false);
    

    Or using jQuery:

    $(document).ready(function(){
    // your code
    });
    
  2. After DOM and Content Load: Which indicate the the DOM and Content load as well. It will ensure not only img tag it will ensure also all images or other relative content loaded. To get this event you should write following way:

    window.addEventListener('load', function() {...})
    

    Or using jQuery:

    $(window).on('load', function() {
     console.log('All assets are loaded')
    })
    

4
这里是唯一一个为 OP 提供了非 jQuery 解决方案并带有清晰解释的答案。 - Velojet
@Hanif DOMContentLoaded事件处理程序对我似乎没有任何作用,但是load事件有。 - Brandon Benefield
1
最后两个例子的行末需要加分号吗? - R. Navega
#2 就是我需要的,运行得非常完美。 - Nhan

37

如果你可以使用jQuery,可以查看load。然后,您可以在元素加载完成后设置您的函数运行。

例如,考虑一个包含简单图像的页面:

<img src="book.png" alt="Book" id="book" />

事件处理程序可以绑定到图像上:

$('#book').load(function() {
  // Handler for .load() called.
});
如果您需要在当前窗口加载所有元素,您可以使用:
$(window).load(function () {
  // run code
});

如果您不能使用jQuery,那么纯JavaScript代码的量基本相同(如果不是更少):

window.onload = function() {
  // run code
};

2
jQuery的load方法不就是使用JavaScript将一个函数绑定到加载事件上吗?这与OP已经在做的有什么不同呢? - Alex Kalicki
据我所知,除了jQuery可能使用addEventListener而不是绑定DOM0的onload属性之外,它不会有任何区别。 - Alnitak
@AlexKalicki 我不能说它使用完全相同的功能,但根据文档,jQuery确保在触发之前加载所有元素,包括图像。如果是这种情况,我倾向于相信会有其他逻辑存在,而且我没有理由不相信文档,尽管我从未遇到OP报告的相同问题。 - Jaime Torres
4
自 JQuery v1.8 版本开始,.load 已经被弃用。 - Adonis K. Kakoulidis
1
最佳解决方案。 - Roberto Sepúlveda Bravo
@AdonisK.Kakoulidis load 事件本身并没有被弃用。目前附加 jQuery 事件(包括 load 和其他事件)的标准方式是 .on( "load", handler ),如链接文档所述,并且仍然有效。 - Sebastian Simon

12

据我所知,你最好的选择是使用

window.addEventListener('load', function() {
    console.log('All assets loaded')
});

使用DOMContentLoaded事件的#1答案是一种倒退,因为DOM将在所有资源加载之前加载。

其他答案建议使用setTimeout,但我强烈反对,因为它完全取决于客户端设备性能和网络连接速度。如果某人处于缓慢的网络环境和/或拥有缓慢的CPU,则页面可能需要几秒钟甚至几十秒钟才能加载完成,因此您无法预测需要多长时间才能触发setTimeout事件。

至于readystatechange事件,在readyState更改时触发,在MDN上指出,这仍然会在load事件之前触发。

Complete

该状态表示加载事件即将触发。


关于最后一段的内容:假设 readystatechange = 'Complete' 表示整个页面和其内容(图片、脚本、CSS)都已加载完成是可以的。虽然它在 load 事件之前,但这里并不重要。 - S.Serpooshan

11
如果你想在HTML页面中调用JavaScript函数,请使用onload事件。当用户代理程序完成窗口或FRAMESET中所有框架的加载时,将触发onload事件。此属性可与BODY和FRAMESET元素一起使用。

如果你想在HTML页面中调用JavaScript函数,请使用onload事件。当用户代理程序完成窗口或FRAMESET中所有框架的加载时,将触发onload事件。此属性可与BODY和FRAMESET元素一起使用。

<body onload="callFunction();">
....
</body>

尝试过了,但无法工作。使用document.addEventListener('DOMContentLoaded',function() {},false)可以正常工作。 - John T

7
这样,您就可以处理已经加载或未加载页面的两种情况:

这种方法可以处理已经加载或未加载页面的两种情况:

document.onreadystatechange = function(){
    if (document.readyState === "complete") {
       myFunction();
    }
    else {
       window.onload = function () {
          myFunction();
       };
    };
}

7
你可以尝试以下方法,无需使用jQuery。

window.addEventListener("load", afterLoaded,false);
function afterLoaded(){
alert("after load")
}


4
window.onload = () => {
  // run in onload
  setTimeout(() => {
    // onload finished.
    // and execute some code here like stat performance.
  }, 10)
}

3
尽管这段代码片段可能是解决方案,但是包括解释真的有助于提高您的帖子质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您建议代码的原因。 - yivi
1
@yivi 如果这不是自动消息的话:对于任何人来说,那段代码的含义都非常明显,特别是因为代码中有注释。 - B''H Bi'ezras -- Boruch Hashem
这对我来说效果最好。即使您删除setTimeout块或仅将其保留在那里;-) - Edang Jeorlie

4
或者你可以尝试以下方法。
$(window).bind("load", function() { 
// code here });

这适用于所有情况。仅当整个页面加载完成后才会触发。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接