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

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


当前回答

使用纯JavaScript的最简单方法。没有jQuery:

document.addEventListener("DOMContentLoaded", function(event) {
   // Your code to run since DOM is loaded and ready
});

其他回答

这个解决方案怎么样?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};

与jQuery相比,使用JavaScript等价物总是很好的。一个原因是依赖的库少了一个,而且它们比jQuery等同物快得多。

jQuery等价物的一个极好的参考是http://youmightnotneedjquery.com/.

就您的问题而言,我从上面的链接中获取了以下代码:)唯一需要注意的是,它仅适用于Internet Explorer 9及更高版本。

function ready(fn) {
    if (document.readyState != 'loading') {
        fn();
    }
    else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

我只使用:

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

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

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

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

实际上,如果您只关心Internet Explorer 9+,那么这段代码就足以取代jQuery.ready:

    document.addEventListener("DOMContentLoaded", callback);

如果您担心Internet Explorer 6和一些非常奇怪和罕见的浏览器,这将奏效:

domReady: function (callback) {
    // Mozilla, Opera and WebKit
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", callback, false);
        // If Internet Explorer, the event model is used
    } else if (document.attachEvent) {
        document.attachEvent("onreadystatechange", function() {
            if (document.readyState === "complete" ) {
                callback();
            }
        });
        // A fallback to window.onload, that will always work
    } else {
        var oldOnload = window.onload;
        window.onload = function () {
            oldOnload && oldOnload();
            callback();
        }
    }
},

有一种基于标准的替代品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 );
}