我想在页面加载后调用一些 JS,这可能涉及延迟,因此我希望首先加载页面以便显示内容......但似乎在渲染完成之前调用了 onLoad 处理程序中的代码。有没有更好的事件我可以使用,当页面“完成”时触发?
澄清一下,我想在页面呈现在屏幕上之后运行一些 JS,所以真的是“发布所有事件”。
沿着时间序列有几个兴趣点。这个通用序列是一个很好的概述,即使不同的浏览器和版本对细节的实现略有不同。(这假设您使用的是原始 Javascript 并且需要最小化跨浏览器问题;由于它对跨浏览器问题的全面内部处理,JQuery 有点不同):
T0] page-begun-- 浏览器已开始在页面上工作,但除此之外,环境还在不断变化。您的 JS 操作可能发生在错误的上下文中,并且在正确的上下文稳定时简单地将其清除。您可能根本不想尝试执行任何 JS。
T1] "onLoad" 事件-- [然而你得到事件:addEventListener("Load"..., window.onload=..., etc.] 页面的所有部分都已被识别并 从服务器下载并在本地系统的内存。为了识别所有部分,已经进行了一些解析。(请注意,“加载”是“下载”的同源词,而不是“解析”或“渲染”。)
您现在拥有了正确的环境,可以开始执行 JS 代码而不必担心丢失任何东西。然而,尝试读取或操作 HTML [getElementById(..., appendChild(..., etc.]) 的操作可能会以奇怪的方式失败,或者可能看起来工作但随后消失,或者可能会做一些与您预期不同的事情.
T2] DOM-几乎-准备好了--这个hack非常简单并且完全跨浏览器。只需将您的 JS <script>...</script> 放在 HTML 的最后,就在 </body> 标记之前。大多数事情都会正常工作,尽管尝试在 <body> 的最后追加或修改 DOM 可能会产生令人惊讶的结果。这并不完全正确,但它在 99% 的情况下都有效。鉴于其简单性和正确操作的可能性非常高,这可能是可行的方法(至少在您不使用 JQuery 的情况下)。
T3] DOM-ready-- [但是你得到事件: addEventListener("DOMContentLoaded"..., window.ondomcontentloaded=..., etc.] 此时 HTML 已经完全解析并且 JS 是 100% 可用的,包括所有读取或操作 HTML 的函数 [getElementById(..., appendChild(..., etc.])。
T4] Render-done--浏览器完成在屏幕上显示内容。有不是任何这样的事件或任何合理的跨浏览器的版本无关的方式来检测这种情况。这也很好,因为无论如何你可能并不真正想要这个。如果浏览器已经在屏幕上显示了页面,然后你操作 DOM,你会得到一个“flash”,之前和之后都至少在屏幕上短暂可见。您可能真正想要的是可以执行任意 JS 代码的点;那是之前的(T3] DOM-ready) 时间点。