在渲染完成之前是.onLoad是否被调用?

时间:2011-03-07 15:23:01

标签: javascript html

我想在页面加载后调用一些JS,这可能涉及延迟,因此我希望首先加载页面以显示内容......但似乎onLoad处理程序中的代码被称为渲染完成之前。我可以使用更好的事件,当页面“完成”时会触发吗?

为了澄清,我希望在页面呈现在屏幕上之后运行一些JS,所以真的是'post-everything事件'。

5 个答案:

答案 0 :(得分:4)

沿着时间顺序有几个兴趣点。这个通用序列是一个很好的概述,即使不同的浏览器和版本实现细节有点不同。 (这假设您使用原始Javascript并且需要最小化跨浏览器问题;使用它对跨浏览器问题的全面内部处理JQuery有点不同):

T0] page-started--浏览器已经开始在页面上工作,但是环境也在不断变化。您的JS操作可能发生在错误的上下文中,并且只有在正确的上下文稳定后才会被刷新。您可能根本不想尝试执行任何JS。

T1]“onLoad”event-- [但是你得到的事件:addEventListener(“加载”......,window.onload = ...等等)页面的所有部分都已被识别并且已下载来自服务器并且位于本地系统的内存中。为了识别所有部分,已经发生了一些解析。(注意,“load”是“下载”的同义词,而不是“解析”也不是“渲染”。)

您现在拥有合适的环境,可以开始执行JS代码,而不必担心丢失任何内容。 HOWEVER ,尝试读取或操作HTML的操作[getElementById(...,appendChild(...等)可能会以奇怪的方式失败,或者可能看似有效但随后消失,或者可能会做一些与你预期不同的事情。

T2] DOM- 几乎 -ready--这个hack非常简单,完全跨浏览器。只需把你的JS< script> ...< / script>在HTML的最后,就在< / body>之前标签。尽管尝试在< body>的最末端附加或修改DOM,但大多数事情都会正常工作。可能产生令人惊讶的结果。这不完全正确,但99%的时间都有效。鉴于它的简单性和正确操作的高概率,这可能是要走的路(至少如果你不使用JQuery)。

T3] DOM-ready-- [但是你得到了事件:addEventListener(“DOMContentLoaded”...,window.ondomcontentloaded = ...等等)此时HTML已被完全解析,JS为100%可用,包括读取或操作HTML的所有函数[getElementById(...,appendChild(...等)。

T4]渲染完成 - 浏览器完成在屏幕上显示内容。有 NOT 任何此类事件或任何合理的跨浏览器版本无关的方法来检测此情况。这也是一样,因为你可能并不是真的想要这个。如果浏览器已经在屏幕上显示了页面并且然后你操作了DOM,那么你将得到一个“闪光”,其中前后都可以在屏幕上看到,至少是短暂的。您可能真正想要的是可以执行任意JS代码的点;这是之前的(T3)DOM-ready)时间点。

答案 1 :(得分:2)

将回调附加到window.onload

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

这将在加载所有资源时触发(可能不是您想要的)。

或者将所有代码放在页面底部(在结束body标记之前)。解析HTML时将运行代码。


FWIW,这是jQuery代码。你看,使用IE和其他浏览器的自定义事件处理程序,但使用window.onload作为后备:

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
    // Use the handy event callback
    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

    // A fallback to window.onload, that will always work
    window.addEventListener( "load", jQuery.ready, false );

    // If IE event model is used
} else if ( document.attachEvent ) {
    // ensure firing before onload,
    // maybe late but safe also for iframes
    document.attachEvent("onreadystatechange", DOMContentLoaded);

    // A fallback to window.onload, that will always work
    window.attachEvent( "onload", jQuery.ready );

    // If IE and not a frame
    // continually check to see if the document is ready
    var toplevel = false;

    try {
        toplevel = window.frameElement == null;
    } catch(e) {}

    if ( document.documentElement.doScroll && toplevel ) {
        doScrollCheck();
    }
}

答案 2 :(得分:0)

与许多JavaScript一样,这取决于您使用的浏览器。

作为@Avitus的回答,您是否看过JQuery文档就绪事件的执行点?这已经在所有浏览器中得到了推广。

答案 3 :(得分:0)

如果您打算使用javascript库(比如jQuery),我宁愿选择$(document).ready()语句,该语句在DOM准备好被操作后调用。

我看到的另一个选项是在HTML页面的末尾包含您的函数调用,以便加载所有HTML内容,以便您可以安全地执行代码

答案 4 :(得分:0)

"The onload event waits for all binary content to download before firing. No kitty-tickilng until then."

正如这篇文章所说的那样,在下载所有二进制内容后调用它,你需要使用jQuery的ready或你自己的函数来监听ready事件。 This project looks interesting.

有许多跨浏览器实现,所以使用jQuery或我链接到的项目。

我已经为我的库编写了自己的函数,它使用了内部方法,因此无法自行运行,但可能会让您感觉自己需要做什么。您可以找到该函数here