我知道有一些方法可以在页面正文加载时收到通知(在加载所有图像和第 3 方资源之前,这会触发 窗口加载 事件),但每个浏览器都不同。

有没有一种确定的方法可以在所有浏览器上执行此操作?

目前我所知道的有:

  • DOM内容已加载 :在 Mozilla、Opera 9 和最新的 WebKit 上。这涉及到向事件添加侦听器:

    document.addEventListener( "DOMContentLoaded", [初始化函数], false );

  • 延迟脚本:在 IE 上,您可以发出带有 @defer 属性的 SCRIPT 标记,该标记仅在 BODY 标记关闭后可靠地加载。

  • 轮询:在其他浏览器上,您可以继续轮询,但是是否有一个标准的轮询,或者您需要在每个浏览器上执行不同的操作?

我希望能够不使用 document.write 或外部文件。

这可以简单地通过 jQuery 完成:

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

但是,我正在编写一个 JS 库,不能指望 jQuery 总是在那里。

有帮助吗?

解决方案

没有跨浏览器的方法来检查 DOM 何时准备好——这就是像 jQuery 这样的库存在的原因,以抽象出令人讨厌的不兼容性。

Mozilla、Opera 和现代 WebKit 支持 DOMContentLoaded 事件。IE 和 Safari 需要一些奇怪的技巧,例如滚动窗口或检查样式表。血淋淋的细节包含在 jQuery 中 bindReady() 功能。

其他提示

我找到了这个页面,它显示了一个紧凑的独立解决方案。它似乎适用于所有浏览器,并解释了如何:

http://www.kryogenix.org/days/2007/09/26/shortloaded

YUI 使用三个测试来做到这一点:对于 Firefox 和最近的 WebKit,会触发 DOMContentLoaded 事件。对于较旧的 Safari,document.readyState 会一直监视,直到它变为“已加载”或“完成”。对于 IE,会创建一个 HTML <P> 标签,并调用“doScroll()”方法,如果 DOM 未准备好,该方法会出错。来源为 雅虎.util.事件 显示 YUI 特定的代码。在 Event.js 中搜索“doScroll”。

使用像 jQuery 这样的库将为您节省无数时间的浏览器不一致问题。

在这种情况下,使用 jQuery 你可以

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

如果您好奇,您可以查看源代码以了解它是如何完成的,但是在当今时代,当库作者为您完成了所有痛苦的工作时,我认为任何人都不应该重新发明这个轮子。

只需取 jQuery 中的相关代码即可,John Resig 已经在 jQuery 中涵盖了此问题的大部分基础知识。

为什么不是这个:

<body>  
  <!-- various content -->  
  <script type="text/javascript">  
  <!--  
    myInit();  
  -->
  </script>  
</body>  

如果我理解正确的话,myInit 将在浏览器在页面中点击它时立即执行,这是正文中的最后一件事。

您正在寻找的精美跨浏览器解决方案...不存在...(想象一下一大群人说“啊啊……”的声音)。

Dom内容已加载 这就是你最好的选择。你仍然需要 polling IE-oldies 的技术。

  1. 尝试使用addEventListener;
  2. 如果不可用(显然是 IE),请检查框架;
  3. 如果不是框架,则滚动直到没有错误抛出(轮询);
  4. 如果是框架,则使用IE事件document.onreadystatechange;
  5. 对于其他不支持的浏览器,请使用旧的 document.onload 事件。

我在以下位置找到了以下代码示例 javascript.info 您可以使用它来覆盖所有浏览器:

function bindReady(handler){

    var called = false

    function ready() { 
        if (called) return
        called = true
        handler()
    }

    if ( document.addEventListener ) { // native event
        document.addEventListener( "DOMContentLoaded", ready, false )
    } else if ( document.attachEvent ) {  // IE

        try {
            var isFrame = window.frameElement != null
        } catch(e) {}

        // IE, the document is not inside a frame
        if ( document.documentElement.doScroll && !isFrame ) {
            function tryScroll(){
                if (called) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 10)
                }
            }
            tryScroll()
        }

        // IE, the document is inside a frame
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }

    // Old browsers
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    else {
        var fn = window.onload // very old browser, copy old onload
        window.onload = function() { // replace by new onload and call the old one
            fn && fn()
            ready()
        }
    }
}

这工作得很好:

setTimeout(MyInitFunction, 0);

使用 setTimeout 可以很好地工作,尽管它的执行时间取决于浏览器。如果您传递零作为超时时间,浏览器将在事情“解决”时执行。

这样做的好处是您可以拥有很多这样的事件,并且不必担心链接 onLoad 事件。

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

ETC。

它们都会在文档加载完成时运行,或者如果您在文档加载后设置一个,它们将在脚本运行完成后运行。

它们的运行顺序尚未确定,并且可能会在浏览器之间发生变化。所以你不能指望 myFunction 之前正在运行 anotherFunction 例如。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top