代码之家  ›  专栏  ›  技术社区  ›  Attila O.

$(document).ready()源

  •  10
  • Attila O.  · 技术社区  · 16 年前

    我想:

    • 内联在闭包中提供文档可读性的代码(不导出)

    window.onload 可以,但我特别想要文档的可读性,而不是等待 事件。

    编辑:

    我对jQuery源代码进行了爬网,并将以下代码片段放在一起:

    var ready = (function () {
        var ready_event_fired = false;
        var ready_event_listener = function (fn) {
    
            // Create an idempotent version of the 'fn' function
            var idempotent_fn = function () {
                if (ready_event_fired) {
                    return;
                }
                ready_event_fired = true;
                return fn();
            }
    
            // The DOM ready check for Internet Explorer
            var do_scroll_check = function () {
                if (ready_event_fired) {
                    return;
                }
    
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                try {
                    document.documentElement.doScroll('left');
                } catch(e) {
                    setTimeout(do_scroll_check, 1);
                    return;
                }
    
                // Execute any waiting functions
                return idempotent_fn();
            }
    
            // If the browser ready event has already occured
            if (document.readyState === "complete") {
                return idempotent_fn()
            }
    
            // Mozilla, Opera and webkit nightlies currently support this event
            if (document.addEventListener) {
    
                // Use the handy event callback
                document.addEventListener("DOMContentLoaded", idempotent_fn, false);
    
                // A fallback to window.onload, that will always work
                window.addEventListener("load", idempotent_fn, 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", idempotent_fn);
    
                // A fallback to window.onload, that will always work
                window.attachEvent("onload", idempotent_fn);
    
                // If IE and not a frame: continually check to see if the document is ready
                var toplevel = false;
    
                try {
                    toplevel = window.frameElement == null;
                } catch (e) {}
    
                if (document.documentElement.doScroll && toplevel) {
                    return do_scroll_check();
                }
            }
        };
        return ready_event_listener;
    })();
    
    // TEST
    var ready_1 = function () {
        alert("ready 1");
    };
    var ready_2 = function () {
        alert("ready 2");
    };
    ready(function () {
        ready_1();
        ready_2();
    });
    

    3 回复  |  直到 16 年前
        1
  •  7
  •   user113716    16 年前

    一个选择就是拿到 core.js 来自github的jQuery文件。

    你也许可以为你不需要的代码精简一些。然后通过YUI压缩机,它应该很小。

    我试过了,代码运行正常:

    $(function() {
        var newDiv = document.createElement('div');
        document.getElementsByTagName('body')[0].appendChild(newDiv);
    });
    

    jQuery 大约是1278字节(压缩)。应该会变小当你gzip。

    唯一的区别是你需要这样称呼它:

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

    YUI压缩:

    (function(){var e=function(i,j){},c=window.jQuery,h=window.$,d,g=false,f=[],b;e.fn={ready:function(i){e.bindReady();if(e.isReady){i.call(document,e)}else{if(f){f.push(i)}}return this}};e.isReady=false;e.ready=function(){if(!e.isReady){if(!document.body){return setTimeout(e.ready,13)}e.isReady=true;if(f){var k,j=0;while((k=f[j++])){k.call(document,e)}f=null}if(e.fn.triggerHandler){e(document).triggerHandler("ready")}}};e.bindReady=function(){if(g){return}g=true;if(document.readyState==="complete"){return e.ready()}if(document.addEventListener){document.addEventListener("DOMContentLoaded",b,false);window.addEventListener("load",e.ready,false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",b);window.attachEvent("onload",e.ready);var i=false;try{i=window.frameElement==null}catch(j){}if(document.documentElement.doScroll&&i){a()}}}};d=e(document);if(document.addEventListener){b=function(){document.removeEventListener("DOMContentLoaded",b,false);e.ready()}}else{if(document.attachEvent){b=function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",b);e.ready()}}}}function a(){if(e.isReady){return}try{document.documentElement.doScroll("left")}catch(i){setTimeout(a,1);return}e.ready()}window.jQuery=window.$=e})();
    

    完整来源(同样,这是 jQuery查询 代码):

    (function() {
    var jQuery = function( selector, context ) {
        },
        _jQuery = window.jQuery,
        _$ = window.$,
    
        rootjQuery,
        readyBound = false,
        readyList = [],
        DOMContentLoaded;
    
    jQuery.fn = {
        ready: function( fn ) {
            jQuery.bindReady();
            if ( jQuery.isReady ) {
                fn.call( document, jQuery );
            } else if ( readyList ) {
                readyList.push( fn );
            }
            return this;
        }
    };
    jQuery.isReady = false;
    jQuery.ready = function() {
            if ( !jQuery.isReady ) {
                if ( !document.body ) {
                    return setTimeout( jQuery.ready, 13 );
                }
                jQuery.isReady = true;
                if ( readyList ) {
                    var fn, i = 0;
                    while ( (fn = readyList[ i++ ]) ) {
                        fn.call( document, jQuery );
                    }
                    readyList = null;
                }
                if ( jQuery.fn.triggerHandler ) {
                    jQuery( document ).triggerHandler( "ready" );
                }
            }
        };
    jQuery.bindReady = function() {
            if ( readyBound ) {
                return;
            }
            readyBound = true;
    
            if ( document.readyState === "complete" ) {
                return jQuery.ready();
            }
            if ( document.addEventListener ) {
                document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                window.addEventListener( "load", jQuery.ready, false );
            } else if ( document.attachEvent ) {
    
                document.attachEvent("onreadystatechange", DOMContentLoaded);
                window.attachEvent( "onload", jQuery.ready );
    
                var toplevel = false;
                try {
                    toplevel = window.frameElement == null;
                } catch(e) {}
                if ( document.documentElement.doScroll && toplevel ) {
                    doScrollCheck();
                }
            }
        };
    rootjQuery = jQuery(document);
    if ( document.addEventListener ) {
        DOMContentLoaded = function() {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            jQuery.ready();
        };
    } else if ( document.attachEvent ) {
        DOMContentLoaded = function() {
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", DOMContentLoaded );
                jQuery.ready();
            }
        };
    }
    function doScrollCheck() {
        if ( jQuery.isReady ) {
            return;
        }
        try {
    
            document.documentElement.doScroll("left");
        } catch(e) {
            setTimeout( doScrollCheck, 1 );
            return;
        }
        jQuery.ready();
    }
    window.jQuery = window.$ = jQuery;
    })();
    

    我肯定还有更多的字节可以删除。

    别忘了:

    /*!
     * jQuery JavaScript Library v1.4.2
     * http://jquery.com/
     *
     * Copyright 2010, John Resig
     * Dual licensed under the MIT or GPL Version 2 licenses.
     * http://jquery.org/license
    */
    
        2
  •  2
  •   Pekka    16 年前

    several implementations for "DOMReady" 但我能找到的大多数函数似乎都有点过时了,所以我不知道它们在IE8之类的环境下会有什么表现。

    我建议使用jQuery的ready(),因为我认为它保证了最大的跨浏览器兼容性。我不是jQuery源代码方面的专家,但是 this 似乎是正确的地点(812-845行或搜索 function bindReady

        3
  •  0
  •   tszming    16 年前

    可以从脚本开始: http://snipplr.com/view/6029/domreadyjs/ ,但没有针对最新的Safari进行优化(但可以工作)(例如,使用计时器而不是支持的DOMContentLoaded)。