我有一个使用$(document).ready的脚本,但它不使用jQuery中的任何其他内容。我想通过删除jQuery依赖项来减轻它。

如何在不使用jQuery的情况下实现我自己的$(document).ready功能?我知道,使用window.onload将不同,因为window.onlead在加载所有图像、帧等后启动。


当前回答

简而言之,我们可以使用JavaScript方法来代替jQuery中使用的$(document).ready():

<script>
    document.addEventListener("DOMContentLoaded", function_name, false);
    function function_name(){
        statements;
    }
</script>

因此,当页面准备就绪(即DOMContentLoaded)时,将调用函数function_name()。

其他回答

跨浏览器(旧浏览器也是)和简单的解决方案:

var docLoaded = setInterval(function () {
    if(document.readyState !== "complete") return;
    clearInterval(docLoaded);

    /*
        Your code goes here i.e. init()
    */
}, 30);

在jsfiddle中显示警报

有一种基于标准的替代品DOMContentLoaded,99%以上的浏览器都支持它,但IE8:

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

jQuery的本机函数比window.onload复杂得多,如下所示。

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            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", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}
(function(f){
  if(document.readyState != "loading") f();
  else document.addEventListener("DOMContentLoaded", f);
})(function(){
  console.log("The Document is ready");
});

穷人的解决方案:

var checkLoad = function() {   
    document.readyState !== "complete" ? setTimeout(checkLoad, 11) : alert("loaded!");   
};  

checkLoad();  

查看Fiddle

添加了这个,我想更好一点,自己的范围,非递归

(function(){
    var tId = setInterval(function() {
        if (document.readyState == "complete") onComplete()
    }, 11);
    function onComplete(){
        clearInterval(tId);    
        alert("loaded!");    
    };
})()

查看Fiddle

我只使用:

setTimeout(function(){
    //reference/manipulate DOM here
});

而且与上面的答案中的document.addEventListener(“DOMContentLoaded”//等不同,它的工作时间可以追溯到IE9——http://caniuse.com/#search=DOMContentLoaded仅表示最近的IE11。

有趣的是,我在2009年偶然发现了这个setTimeout解决方案:检查DOM的准备是否过度?,我的意思是“使用各种框架的更复杂的方法来检查DOM的就绪性是否过分”。

我对这种技术为什么有效的最好解释是,当使用这样一个setTimeout的脚本到达时,DOM正处于解析过程中,因此setTimeout中的代码的执行会延迟到该操作完成。