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

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


当前回答

这个问题很久以前就被问过了。对于任何看到这个问题的人来说,现在有一个名为“您可能不需要jquery”的网站,它按所需的IE支持级别分解了jquery的所有功能,并提供了一些替代的、较小的库。

IE8文档就绪脚本,根据您可能不需要jquery

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

其他回答

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

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

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

大多数普通的JS Ready函数都不考虑在文档加载后设置DOMContentLoaded处理程序的情况——这意味着函数永远不会运行。如果在异步外部脚本(<script async src=“file.js”></script>)中查找DOMContentLoaded,则可能会发生这种情况。

只有当文档的readyState尚未交互或完成时,下面的代码才会检查DOMContentLoaded。

var DOMReady = function(callback) {
  document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback());
};
DOMReady(function() {
  //DOM ready!
});

如果您也想支持IE:

var DOMReady = function(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback());
    } else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading') {
                callback();
            }
        });
    }
};

DOMReady(function() {
  // DOM ready!
});

最小且100%工作

我已经从PlainJS中选择了答案,它对我来说很好。它扩展了DOMContentLoaded,因此它可以在所有浏览器中被接受。


此函数等效于jQuery的$(document).ready()方法:

document.addEventListener('DOMContentLoaded', function(){
    // do something
});

然而,与jQuery不同的是,这段代码只能在现代浏览器中正常运行(IE>8),如果在插入此脚本时(例如通过Ajax)已经呈现了文档,则无法正常运行。因此,我们需要稍微扩展一下:

function run() {
    // do something
}

// in case the document is already rendered
if (document.readyState!='loading') run();
// modern browsers
else if (document.addEventListener) 
document.addEventListener('DOMContentLoaded', run);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
    if (document.readyState=='complete') run();
});

这基本上涵盖了所有的可能性,是jQuery助手的可行替代品。

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

这个解决方案怎么样?

// 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();
};