$ (दस्तावेज़)। jQuery के बिना पहले से ही समकक्ष


2016

मेरे पास एक स्क्रिप्ट है जो उपयोग करती है $(document).ready, लेकिन यह jQuery से कुछ और उपयोग नहीं करती है। मैं jQuery की निर्भरता को हटाकर इसे हल्का करना चाहता हूं।

मैं $(document).readyjQuery का उपयोग किए बिना अपनी खुद की कार्यक्षमता कैसे लागू कर सकता हूं ? मुझे पता है कि उपयोग window.onloadकरना समान नहीं होगा, क्योंकि window.onloadसभी छवियों, फ़्रेमों आदि के बाद आग लोड हो गई है।


296
... और निश्चित रूप से समान कार्यक्षमता नहीं है।
जोएल म्यूलर

40
जैसा कि इस उत्तर में कहा गया है, यदि आप jQuery से सभी चाहते हैं, तो आप $(document).readyशीर्ष पर के बजाय पृष्ठ के सबसे निचले भाग में अपना कोड चलाकर उस समस्या को आसानी से हल कर सकते हैं। HTML5Boilerplate इस सटीक दृष्टिकोण का उपयोग करता है।
ब्लेज़मॉन्गर

3
क्यों न केवल DOMContentLoaded का उपयोग किया जाए? यह IE9 + caniuse.com/domcontentloaded developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Brock

मैंने अपने कॉल को दस्तावेज़ के आखिरी में रखा और इससे मेरी समस्या हल हो गई। जब फ़ंक्शन को कॉल किया जाता है, तो सब कुछ लोड होता है।
इग्नाइटकॉडर्स

जवाबों:


1440

एक मानक आधारित प्रतिस्थापन है, DOMContentLoadedजो 98% से अधिक ब्राउज़रों द्वारा समर्थित है , हालांकि 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 );
}

19
एक वास्तविक कामकाजी सादा जावास्क्रिप्ट कार्यान्वयन यहाँ अगर कोई कोड चाहता है तो वे इसमें ड्रॉप कर सकते हैं: stackoverflow.com/questions/9899372/…
jfriend00

4
jQuery DOM तैयार कोड सरल प्रतीत होता है: github.com/jquery/jquery/blob/master/src/core/ready/js
जोस नोबेल

2
@JoseNobile क्योंकि उन्होंने पुराने ब्राउज़र समर्थन को गिरा दिया
huysentruitw

16
मुझे लगता है कि हम IE8 ...;) से आगे बढ़ने के लिए तैयार हैं। लिंक के लिए धन्यवाद, @JoseNobile।
कोन एंटाकोस

13
अगर स्क्रिप्ट को बाद में लोड किया जाता है तो DOMContentLoaded काम नहीं करेगी। JQuery दस्तावेज़ तैयार हमेशा निष्पादित करता है।
जारेड इनसेल

343

संपादित करें:

यहाँ jQuery के तैयार के लिए एक व्यवहार्य प्रतिस्थापन है

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

ready(function(){
    // do something
});

Https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/ से लिया गया

एक और अच्छा डोमरी कार्य यहाँ https://stackoverflow.com/a/9899701/175071 से लिया गया है


जैसा कि स्वीकृत उत्तर पूर्ण से बहुत दूर था, मैंने jQuery.ready()jQuery 1.6.2 के आधार पर एक "तैयार" फ़ंक्शन को एक साथ जोड़ा।

var ready = (function(){

    var readyList,
        DOMContentLoaded,
        class2type = {};
        class2type["[object Boolean]"] = "boolean";
        class2type["[object Number]"] = "number";
        class2type["[object String]"] = "string";
        class2type["[object Function]"] = "function";
        class2type["[object Array]"] = "array";
        class2type["[object Date]"] = "date";
        class2type["[object RegExp]"] = "regexp";
        class2type["[object Object]"] = "object";

    var ReadyObj = {
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        readyWait: 1,
        // Hold (or release) the ready event
        holdReady: function( hold ) {
            if ( hold ) {
                ReadyObj.readyWait++;
            } else {
                ReadyObj.ready( true );
            }
        },
        // Handle when the DOM is ready
        ready: function( wait ) {
            // Either a released hold or an DOMready/load event and not yet ready
            if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                if ( !document.body ) {
                    return setTimeout( ReadyObj.ready, 1 );
                }

                // Remember that the DOM is ready
                ReadyObj.isReady = true;
                // If a normal DOM Ready event fired, decrement, and wait if need be
                if ( wait !== true && --ReadyObj.readyWait > 0 ) {
                    return;
                }
                // If there are functions bound, to execute
                readyList.resolveWith( document, [ ReadyObj ] );

                // Trigger any bound ready events
                //if ( ReadyObj.fn.trigger ) {
                //    ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
                //}
            }
        },
        bindReady: function() {
            if ( readyList ) {
                return;
            }
            readyList = ReadyObj._Deferred();

            // Catch cases where $(document).ready() is called after the
            // browser event has already occurred.
            if ( document.readyState === "complete" ) {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                return setTimeout( ReadyObj.ready, 1 );
            }

            // Mozilla, Opera and webkit nightlies currently support this event
            if ( document.addEventListener ) {
                // Use the handy event callback
                document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                // A fallback to window.onload, that will always work
                window.addEventListener( "load", ReadyObj.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", DOMContentLoaded );

                // A fallback to window.onload, that will always work
                window.attachEvent( "onload", ReadyObj.ready );

                // 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 ) {
                    doScrollCheck();
                }
            }
        },
        _Deferred: function() {
            var // callbacks list
                callbacks = [],
                // stored [ context , args ]
                fired,
                // to avoid firing when already doing so
                firing,
                // flag to know if the deferred has been cancelled
                cancelled,
                // the deferred itself
                deferred  = {

                    // done( f1, f2, ...)
                    done: function() {
                        if ( !cancelled ) {
                            var args = arguments,
                                i,
                                length,
                                elem,
                                type,
                                _fired;
                            if ( fired ) {
                                _fired = fired;
                                fired = 0;
                            }
                            for ( i = 0, length = args.length; i < length; i++ ) {
                                elem = args[ i ];
                                type = ReadyObj.type( elem );
                                if ( type === "array" ) {
                                    deferred.done.apply( deferred, elem );
                                } else if ( type === "function" ) {
                                    callbacks.push( elem );
                                }
                            }
                            if ( _fired ) {
                                deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
                            }
                        }
                        return this;
                    },

                    // resolve with given context and args
                    resolveWith: function( context, args ) {
                        if ( !cancelled && !fired && !firing ) {
                            // make sure args are available (#8421)
                            args = args || [];
                            firing = 1;
                            try {
                                while( callbacks[ 0 ] ) {
                                    callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
                                }
                            }
                            finally {
                                fired = [ context, args ];
                                firing = 0;
                            }
                        }
                        return this;
                    },

                    // resolve with this as context and given arguments
                    resolve: function() {
                        deferred.resolveWith( this, arguments );
                        return this;
                    },

                    // Has this deferred been resolved?
                    isResolved: function() {
                        return !!( firing || fired );
                    },

                    // Cancel
                    cancel: function() {
                        cancelled = 1;
                        callbacks = [];
                        return this;
                    }
                };

            return deferred;
        },
        type: function( obj ) {
            return obj == null ?
                String( obj ) :
                class2type[ Object.prototype.toString.call(obj) ] || "object";
        }
    }
    // The DOM ready check for Internet Explorer
    function doScrollCheck() {
        if ( ReadyObj.isReady ) {
            return;
        }

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

        // and execute any waiting functions
        ReadyObj.ready();
    }
    // Cleanup functions for the document ready method
    if ( document.addEventListener ) {
        DOMContentLoaded = function() {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            ReadyObj.ready();
        };

    } else if ( document.attachEvent ) {
        DOMContentLoaded = function() {
            // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", DOMContentLoaded );
                ReadyObj.ready();
            }
        };
    }
    function ready( fn ) {
        // Attach the listeners
        ReadyObj.bindReady();

        var type = ReadyObj.type( fn );

        // Add the callback
        readyList.done( fn );//readyList is result of _Deferred()
    }
    return ready;
})();

कैसे इस्तेमाल करे:

<script>
    ready(function(){
        alert('It works!');
    });
    ready(function(){
        alert('Also works!');
    });
</script>

मुझे यकीन नहीं है कि यह कोड कितना कार्यात्मक है, लेकिन इसने मेरे सतही परीक्षणों के साथ ठीक काम किया। इसमें काफी समय लगा, इसलिए मुझे उम्मीद है कि आप और अन्य लोग इससे लाभान्वित हो सकते हैं।

पुनश्च: मैं इसे संकलित करने का सुझाव देता हूं ।

या आप http://dustindiaz.com/smallest-domready-ever का उपयोग कर सकते हैं :

function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()}
r(function(){/*code to run*/});

या देशी फ़ंक्शन यदि आपको केवल नए ब्राउज़रों का समर्थन करने की आवश्यकता है (jQuery के तैयार के विपरीत, यह तब नहीं चलेगा जब आप इसे पृष्ठ को समाप्त करने के बाद जोड़ देंगे)

document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})

14
@TimoHuovinen विकल्प: Zepto.js (9.1 केबी), स्नैक.जेएस (8.1 केबी), $ डोम (2.3 केबी), और 140 मेडले (0.5 केबी)। संपादित करें: आप एंडर पर भी नज़र डाल सकते हैं।
फ्रेडरिक क्रौटवल्ड

2
@FrederikKrautwald $ डोम लगता है कि मुझे क्या चाहिए, लेकिन यह बिल फिट होने पर निश्चित नहीं है। Zepto भी वास्तव में होनहार लग रहा है, साझा करने के लिए धन्यवाद!
तैमू हुओवेन

@TimoHuovinen यदि आपने Ender को नहीं देखा है, तो आपको निश्चित रूप से, enderjs.com पर एक नज़र डालनी चाहिए
फ्रेडरिक क्राउटवल्ड

2
@Timo Huovinen: आपका प्रश्न वास्तव में, वास्तव में व्यापक है! जब jQuery बनाया गया था, तो यह ब्राउज़रों द्वारा उत्पन्न क्रॉस ब्राउज़रों के बहुत सारे मुद्दों को फिट करता था जो आज कम महत्वपूर्ण हैं। आज, "जावास्क्रिप्ट केवल" इससे आसान था। इस समय, "एक बड़ा 20kb संपीड़ित, जिसमें सभी शामिल हैं" निश्चित रूप से बहुत सारे कारणों से एक अच्छा विचार था जो मैं उन सभी को सूचीबद्ध नहीं करना पसंद करता हूं।
dotpush

1
मुझे यह पसंद नहीं है। यदि लोग इस उत्तर को पसंद करते हैं, तो अपने आप से पूछें कि आप पहले स्थान पर jQuery को क्यों छोड़ना चाहते हैं। यह थोड़ा व्यर्थ है यदि आप बस उसी कार्यक्षमता को निकालने के लिए जा रहे हैं, जो कि ब्राउज़र के सभी कमबैक आपके बंडल में वापस आती है। क्या पहली जगह में jQuery से बचने की पूरी बात नहीं है?
फिल

208

तीन विकल्प:

  1. अगर script शरीर का अंतिम टैग है, तो स्क्रिप्ट स्क्रिप्ट निष्पादित होने से पहले DOM तैयार होगा
  2. जब DOM तैयार हो जाता है, तो "readyState" बदलकर "पूरा" हो जाएगा
  3. सब कुछ 'DOMContentLoaded' इवेंट श्रोता के अंतर्गत रखें

onreadystatechange

  document.onreadystatechange = function () {
     if (document.readyState == "complete") {
     // document is ready. Do your stuff here
   }
 }

स्रोत: एमडीएन

DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
   console.log('document is ready. I can sleep now');
});

पाषाण युग के ब्राउज़रों के बारे में चिंतित: jQuery स्रोत कोड पर जाएं औरreadyफ़ंक्शन काउपयोग करें। उस स्थिति में आप पूरी लाइब्रेरी को पारसिंग नहीं कर रहे हैं या नहीं कर रहे हैं।


3
यह दूसरा उदाहरण चिह्नित उत्तरों की तुलना में बहुत अधिक सुरुचिपूर्ण और रसीला है। इसे सही के रूप में चिह्नित क्यों नहीं किया गया?
0112

2
DOMContentLoaded चीज़ के लिए अभी भी +1, यह वही करता है जो मैं चाहता था।
ट्रिपल

1
onreadystatechange ने मेरे लिए चाल चली ... async जेकरी लोडिंग के बाद कुछ स्क्रिप्ट चलाने की जरूरत थी।
अब्राम

2
एक FYI के रूप में, # 1 पूरी तरह से सच नहीं है। DOM के संपन्न होने से पहले लोड करना पृष्ठ के अंत में स्क्रिप्ट के लिए काफी संभव है। इसलिए श्रोता श्रेष्ठ हैं। जब ब्राउज़र किया जाता है तो वे सुनते हैं। इसे अंत में डालकर अपनी उंगलियों को पार कर रहा है कि स्क्रिप्ट लोड ब्राउज़र की तुलना में धीमा था।
मचाविटी

1
यह वैरिएंट तब भी काम करेगा जब दस्तावेज़ पहले ही लोड हो रहा है, कृपया अपना (imo सबसे अच्छा) उत्तर अपडेट करें यदि आप कर सकते हैं: if (document.readyState == 'पूरा') {init (); } और {document.onreadystatechange = function () {if (document.readyState == 'पूरा') {init (); }}}
ZPiDER

87

समापन टैग से पहले अपना <script>/*JavaScript code*/</script>अधिकार रखें । </body>

बेशक, यह हर किसी के उद्देश्यों के अनुरूप नहीं हो सकता क्योंकि इसके लिए जावास्क्रिप्ट फ़ाइल में कुछ करने के बजाय HTML फ़ाइल को बदलने की आवश्यकता होती है document.ready, लेकिन ...


यह मुझे लगता है कि संगतता मुद्दे थे, जैसे, पृष्ठ अभी तक तैयार नहीं है, आप इन और उन ब्राउज़रों में ऐसा नहीं कर सकते। दुर्भाग्य से मुझे अधिक स्पष्ट रूप से याद नहीं है। फिर भी एक तरह से +1 जो सभी मामलों में 99% के करीब है (और याहू द्वारा सुझाया गया है!)।
बोल्डवेयेन

7
दरअसल, पृष्ठ के निचले भाग में एक स्क्रिप्ट तत्व डालना लगभग एक सही समाधान है। यह क्रॉस-ब्राउज़र का काम करता है और डॉक्यूमेंट को पहले से ही परफेक्ट बना देता है। एकमात्र नुकसान यह है कि यह (थोड़ा सा) कुछ स्मार्ट कोड का उपयोग करने से अधिक अप्रिय है, आपको उस स्क्रिप्ट के उपयोगकर्ता से पूछना होगा जिसे आप अपने तैयार या इनिट फ़ंक्शन को कॉल करने के लिए एक अतिरिक्त स्क्रिप्ट टुकड़ा जोड़ने के लिए बना रहे हैं।
स्टिजन डे विट

@StijndeWitt - एक init फ़ंक्शन को कॉल करने के बारे में आपका क्या मतलब है? एक स्क्रिप्ट जो दस्तावेज़ का उपयोग करती है। पहले से ही इसे कॉल करने के लिए अन्य क्लाइंट कोड की आवश्यकता नहीं है, यह स्व-निहित है, और इसके समतुल्य जहां कोड शरीर के अंत में शामिल है, वह भी स्व-निहित हो सकता है और नहीं इसे कॉल करने के लिए अन्य कोड की आवश्यकता होती है।
nnnnnn

1
क्लोजिंग बॉडी टैग के बाद और समापन टैग से पहले स्क्रिप्ट को क्यों नहीं रखा गया </html>?
चार्ल्स होलब्रो

1
@CharlesHolbrow हालांकि सभी ब्राउज़रों इसे सही ढंग से व्याख्या करेगा, यदि आप इसे वैध एचटीएमएल होना चाहता हूँ, htmlटैग केवल शामिल करना चाहिए headऔर body
अल्वारो मोंटोरो

66

गरीब आदमी का हल:

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

checkLoad();  

फिडल देखें

यह एक जोड़ा, थोड़ा बेहतर मुझे लगता है, खुद की गुंजाइश, और गैर पुनरावर्ती

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

फिडल देखें


8
@PhilipLangford या बस इसे अंदर डालें setIntervalऔर पुनरावृत्ति को पूरी तरह से हटा दें।
एलेक्स डब्ल्यू

1
@ रेवरेन, हम्म तुम ठीक कह रहे हो, मुझे पूरा यकीन है कि जब मैंने इसे पोस्ट किया था तो मैंने इसका परीक्षण किया था। वैसे भी, यह केवल और भी सरल हो गया, अब फ़ंक्शन केवल कॉल किया जाता है, कोई रैपिंग नहीं।
जैकब स्टर्नबर्ग

24
यह सेक्सी नहीं है। कोई खेद नहीं। सामान का पता लगाने के लिए टाइमर / अंतराल का उपयोग करना "काम" हो सकता है, लेकिन अगर आप इस तरह की प्रोग्रामिंग करते रहते हैं, तो इसके नमक के लायक कोई बड़ा प्रोजेक्ट नाक में गोता लगाने वाला है। इस तरह से एक साथ सामान हैक न करें। सही से करो। कृप्या। इस तरह का कोड विकास पारिस्थितिकी तंत्र को नुकसान पहुंचाता है क्योंकि एक बेहतर समाधान है और आप इसे जानते हैं।
दुवेवाद

1
मुझे लगता है कि यह उत्तर डस्टइंडियाज़ के बहुत करीब है। यह पहले से ही है, इसलिए मैंने स्क्रिप्ट में सुधार किया: jsfiddle.net/iegik/PT7x9
यानी 13

1
@ReidBlomquist हाँ, और यह एक "गलत" तरीका है, और यही मैं इंगित कर रहा हूँ (भले ही थोड़ा बहुत, मुझे पता है)। आप कह सकते हैं कि गलत तरीके से करने से यह किसी भी तरह से पारिस्थितिक तंत्र की "मदद" कर रहा है, लेकिन समस्या यह है कि खराब कोड की मात्रा के साथ जो लोग "अच्छे" कोड के लिए लेते हैं क्योंकि उनके पास कोई बेहतर जानने का अनुभव नहीं है। पारिस्थितिकी तंत्र की मदद नहीं करता है, क्योंकि तब वे उस बुरे कोड को लेने जा रहे हैं और इसे एक वास्तविक उत्पादन वास्तु समाधान में लागू करते हैं। इसलिए, मुझे लगता है कि, हमें इस "गिरावट" पर राय अलग-अलग करनी होगी।
दुवेद

34

मैं इसका उपयोग करता हूं:

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

नोट: यह शायद केवल नए ब्राउज़रों के साथ काम करता है, विशेष रूप से ये: http://caniuse.com/#feat=domcontentloaded


13
IE9 और वास्तव में ऊपर
पास्कलियस

यदि आप document_start या document_idle ईवेंट को हुक कर रहे थे तो यह क्रोम एक्सटेंशन सामग्री स्क्रिप्ट में भी बहुत अच्छा काम करता है।
वोलोमाइक

21

वास्तव में, यदि आप केवल 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();
        }
    }
},

18

यह सवाल काफी पहले पूछा गया था। किसी को भी इस प्रश्न को देखने के लिए, अब एक साइट है जिसे "आपको 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();
        });
}

मुझे आश्चर्य है कि इसके 'onreadystatechange'बजाय आवश्यक क्यों हैdocument.attachEvent('onload', fn);
ल्यूक

13

मैं हाल ही में एक मोबाइल साइट के लिए इसका उपयोग कर रहा था। यह "प्रो जावास्क्रिप्ट तकनीक" से जॉन रेजिग का सरलीकृत संस्करण है। यह addEvent पर निर्भर करता है।

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load", isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();

13
इस कोड के साथ सावधान रहें। यह पहले से ही $ (दस्तावेज़) के बराबर नहीं है। यह कोड डॉक्यूमेंट के लिए तैयार होने पर कॉलबैक को ट्रिगर करता है।
Karolis

12

क्रॉस-ब्राउज़र (पुराने ब्राउज़र भी) और एक सरल समाधान:

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

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

Jsfiddle में अलर्ट दिखा रहा है


इसके अलावा अगर डोम को लोड करने में 30ms से अधिक समय लगता है, तो आप कोड नहीं चलाएंगे।
क्लेक्लेफ़

1
@Quelklef जो सेट है। Invalval ने सेट टाइमआउट नहीं किया
Pawel

11

JQuery का उत्तर मेरे लिए बहुत उपयोगी था। थोड़े से फेरबदल के साथ इसने मेरी जरूरतों को अच्छी तरह से पूरा किया। मुझे उम्मीद है कि यह किसी और की मदद करता है।

function onReady ( callback ){
    var addListener = document.addEventListener || document.attachEvent,
        removeListener =  document.removeEventListener || document.detachEvent
        eventName = document.addEventListener ? "DOMContentLoaded" : "onreadystatechange"

    addListener.call(document, eventName, function(){
        removeListener( eventName, arguments.callee, false )
        callback()
    }, false )
}

कुछ ब्राउज़रों पर, removeListenerसंदर्भ के रूप में दस्तावेज़ के साथ बुलाया जाना चाहिए। removeListener.call(document, ...
रॉन

9

यहाँ DOM तैयार का परीक्षण करने के लिए सबसे छोटा कोड स्निपेट है जो सभी ब्राउज़रों में काम करता है (यहाँ तक कि IE 8):

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

इस जवाब को देखें ।


6

बस इसे अपने HTML पृष्ठ के निचले भाग में जोड़ें ...

<script>
    Your_Function();
</script>

क्योंकि, HTML डॉक्युमेंट्स को टॉप-बॉटम द्वारा पार्स किया जाता है।


7
आप कैसे जानते हैं कि जब इस कोड को निष्पादित किया जाता है तो DOM बनाया जाता है? लोड और सीएसएस सहित पार्स? ब्राउज़र API DOMContentLoaded उसी के लिए डिज़ाइन किया गया है।
दान

यह वास्तव में इस बात पर निर्भर करता है कि वह js के साथ क्या करना चाहता है। अगर वह वास्तव में कुछ करने की जरूरत है जब पृष्ठ समाप्त हो गया है या नहीं।
डेवफ्रैसोनी

5

यह रॉक सॉलिड एडवेंट () और http://www.braksator.com/how-to-make-your-own-jearery में देखने लायक है

यहां साइट डाउन होने की स्थिति में कोड होता है

function addEvent(obj, type, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
        EventCache.add(obj, type, fn);
    }
    else {
        obj["on"+type] = obj["e"+type+fn];
    }
}

var EventCache = function(){
    var listEvents = [];
    return {
        listEvents : listEvents,
        add : function(node, sEventName, fHandler){
            listEvents.push(arguments);
        },
        flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
            };
        }
    };
}();

// Usage
addEvent(window, 'unload', EventCache.flush);
addEvent(window, 'load', function(){alert("I'm ready");});

दूसरी कड़ी टूट गई है।
पीटर मोर्टेंसन


4

DOM तैयार होने के बाद यह क्रॉस-ब्राउज़र कोड एक फ़ंक्शन को कॉल करेगा:

var domReady=function(func){
    var scriptText='('+func+')();';
    var scriptElement=document.createElement('script');
    scriptElement.innerText=scriptText;
    document.body.appendChild(scriptElement);
};

यहां देखिए यह कैसे काम करता है:

  1. फ़ंक्शन की पहली पंक्ति उस फ़ंक्शन domReadyकी toStringविधि का प्रतिनिधित्व करती है जिसे आप पास करने वाले फ़ंक्शन का एक स्ट्रिंग प्रतिनिधित्व प्राप्त करते हैं और इसे एक अभिव्यक्ति में लपेटता है जो तुरंत फ़ंक्शन को कॉल करता है।
  2. बाकी domReadyअभिव्यक्ति के साथ एक स्क्रिप्ट तत्व बनाता है और इसे जोड़ता हैbody दस्तावेज़ में ।
  3. bodyDOM तैयार होने के बाद ब्राउज़र स्क्रिप्ट स्क्रिप्ट को रन करता है।

उदाहरण के लिए, यदि आप ऐसा करते हैं: domReady(function(){alert();});निम्नलिखित bodyतत्व के लिए संलग्न होगा :

 <script>(function (){alert();})();</script>

ध्यान दें कि यह केवल उपयोगकर्ता द्वारा परिभाषित कार्यों के लिए काम करता है। निम्नलिखित काम नहीं करेगा:domReady(alert);


3

इस समाधान के बारे में कैसे?

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

3
आप "लोड" के साथ विंडो पर addEventListener का उपयोग कर सकते हैं। श्रोताओं को एक के बाद एक निष्पादित किया जाता है और न ही मैन्युअल रूप से जंजीरों की आवश्यकता होती है।
जफ्फी

1
लेकिन लोड तैयार होने से अलग है। दस्तावेज़ के 'तैयार' होने से पहले भी 'लोड' होता है। एक तैयार दस्तावेज में अपना डोम लोड किया गया है, एक भरी हुई खिड़की जरूरी नहीं कि डोम तैयार हो। अच्छा जवाब हालांकि
Mzn

1
@Mzn: मुझे लगता है कि पीछे की ओर है। मुझे लगता है कि तैयार दस्तावेज़ विंडो लोड घटना से पहले होता है । "सामान्य तौर पर, सभी छवियों के पूरी तरह से लोड होने की प्रतीक्षा करना आवश्यक नहीं है। यदि कोड को पहले निष्पादित किया जा सकता है, तो इसे पहले से ही। ( api.jquery.com/load-event )
टायलर रिक

यह पृष्ठ पर शेष window.onload ईवेंट को ओवरराइड करेगा और समस्याएँ पैदा करेगा। यह मौजूदा एक के ऊपर घटना को जोड़ना चाहिए।
तेमन शिपाही

लोड घटना बहुत देर हो सकती है। जब थर्ड पार्टी एक्सटर्नल जेएस / इमेज के आधार पर इसका उपयोग करना दर्दनाक होता है ... एक गैर-उत्तरदायी सर्वर जिसे आप नियंत्रित नहीं करते हैं और सब कुछ विफल हो जाता है। DOMContentLoaded का उपयोग करना केवल एक अनुकूलन नहीं है, यह अधिक सुरक्षित भी है!
डॉटपुष

3

JQuery की तुलना में जावास्क्रिप्ट समकक्षों का उपयोग करना हमेशा अच्छा होता है। एक कारण पर निर्भर करने के लिए एक कम पुस्तकालय है और वे jQuery समकक्षों की तुलना में बहुत तेज हैं।

JQuery समकक्षों के लिए एक शानदार संदर्भ http://youmightnotneedjquery.com/ है

जहाँ तक आपके प्रश्न का सवाल है, मैंने नीचे दिए गए कोड को उपरोक्त लिंक से लिया है :) केवल चेतावनी यह है कि यह केवल Internet Explorer 9 और बाद में काम करता है ।

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

3

सबसे न्यूनतम और 100% काम कर रहे हैं

मैंने इसका जवाब प्लेनज से लिया है और यह मेरे लिए ठीक काम कर रहा है। इसका विस्तार DOMContentLoadedइतना है कि इसे सभी ब्राउज़रों में स्वीकार किया जा सकता है।


यह फ़ंक्शन jQuery की $(document).ready()विधि के बराबर है :

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

हालाँकि, jQuery के विपरीत, यह कोड केवल आधुनिक ब्राउज़रों (IE> 8) में ठीक से चलेगा और यह उस स्थिति में नहीं होगा जब यह स्क्रिप्ट सम्मिलित किए जाने के समय दस्तावेज़ पहले से ही मौजूद हो (जैसे अजाक्स के माध्यम से)। इसलिए, हमें इसे थोड़ा बढ़ाने की आवश्यकता है:

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 सहायक के लिए एक व्यवहार्य प्रतिस्थापन है।


3

यह वर्ष 2020 है और <script>टैग में deferविशेषता है।

उदाहरण के लिए:

<script src="demo_defer.js" defer></script>

यह निर्दिष्ट करता है कि पृष्ठ निष्पादित होने पर स्क्रिप्ट निष्पादित हो जाती है।

https://www.w3schools.com/tags/att_script_defer.asp


2

हमने पाया कि हमारा एक त्वरित और गंदा क्रॉस ब्राउज़र कार्यान्वयन जो न्यूनतम कार्यान्वयन के साथ अधिकांश सरल मामलों के लिए चाल कर सकता है:

window.onReady = function onReady(fn){
    document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};

क्या है doc.body?
नबी काज

2

यहाँ प्रस्तुत setTimeout / setInterval समाधान केवल विशिष्ट परिस्थितियों में काम करेंगे।

समस्या विशेष रूप से पुराने Internet Explorer संस्करणों में 8 तक दिखाई देती है।

इन setTimeout / setInterval समाधानों की सफलता को प्रभावित करने वाले चर हैं:

1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding

मूल (मूल जावास्क्रिप्ट) कोड इस विशिष्ट समस्या को हल करने वाला है:

https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)

यह वह कोड है जिसमें से jQuery टीम ने अपना कार्यान्वयन बनाया है।


1

यहां मैं जो उपयोग करता हूं, वह तेज है और मेरे विचार से सभी आधारों को शामिल करता है; IE <9 को छोड़कर सब कुछ के लिए काम करता है।

(() => { function fn() {
    // "On document ready" commands:
    console.log(document.readyState);
};  
  if (document.readyState != 'loading') {fn()}
  else {document.addEventListener('DOMContentLoaded', fn)}
})();

यह सभी मामलों को पकड़ने के लिए लगता है:

  • यदि DOM पहले से तैयार है (अगर DOM "लोड नहीं कर रहा है", लेकिन या तो "इंटरएक्टिव" या "पूर्ण") तो तुरंत फायर हो जाता है
  • यदि DOM अभी भी लोड हो रहा है, तो यह DOM (कब) उपलब्ध है, इसके लिए एक इवेंट श्रोता सेट करता है।

DOMContentLoaded घटना IE9 और अन्य सभी चीज़ों में उपलब्ध है, इसलिए मुझे लगता है कि व्यक्तिगत रूप से इसका उपयोग करना ठीक है। यदि आप अपने कोड को ES2015 से ES5 में ट्रांसपाइल नहीं कर रहे हैं, तो एक नियमित अनाम फ़ंक्शन को तीर फ़ंक्शन घोषणा को फिर से लिखें।

यदि आप सभी संपत्तियां लोड होने तक इंतजार करना चाहते हैं, तो सभी प्रदर्शित चित्र आदि तो इसके बजाय window.onload का उपयोग करें।


1

यदि आपको बहुत पुराने ब्राउज़रों का समर्थन करने की आवश्यकता नहीं है, तो यहां एक तरीका यह भी है जब आपकी बाहरी स्क्रिप्ट को async विशेषता के साथ लोड किया गया हो :

HTMLDocument.prototype.ready = new Promise(function(resolve) {
   if(document.readyState != "loading")
      resolve();
   else
      document.addEventListener("DOMContentLoaded", function() {
         resolve();
      });
});

document.ready.then(function() {
   console.log("document.ready");
});

0

IE9 + के लिए:

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

0

यदि आप बॉडी के निचले हिस्से के पास jQuery लोड कर रहे हैं, लेकिन jQuery (<func>) या jQuery (डॉक्यूमेंट) को लिखने वाले कोड के साथ समस्या आ रही है। (<func>), jqShim देखें। । Github पर देखें।

अपने स्वयं के दस्तावेज़ तैयार फ़ंक्शन को फिर से बनाने के बजाय, यह केवल तब तक फ़ंक्शन पर रहता है जब तक कि jQuery उपलब्ध नहीं होता है, तब उम्मीद के मुताबिक jQuery के साथ आगे बढ़ता है। JQuery को शरीर के निचले भाग में ले जाने का बिंदु पेज लोड को गति देना है, और आप अभी भी इसे अपने टेम्पलेट के सिर में jqShim.min.js को इनलाइन करके पूरा कर सकते हैं।

मैंने वर्डप्रेस की सभी लिपियों को पाद लेख तक ले जाने के लिए इस कोड को लिखना समाप्त कर दिया , और यह शिम कोड अब सीधे हेडर में बैठता है।


0

इसे इस्तेमाल करे:

function ready(callback){
    if(typeof callback === "function"){
        document.addEventListener("DOMContentLoaded", callback);
        window.addEventListener("load", callback);
    }else{
        throw new Error("Sorry, I can not run this!");
    }
}
ready(function(){
    console.log("It worked!");
});

Lol आप कॉलबैक को दो बार चलाने वाले हैं
एंड्रयू

0
function onDocReady(fn){ 
    $d.readyState!=="loading" ? fn():document.addEventListener('DOMContentLoaded',fn);
}

function onWinLoad(fn){
    $d.readyState==="complete") ? fn(): window.addEventListener('load',fn);
} 

onDocReadyजब HTML डोम पूरी तरह से एक्सेस / पार्स / हेरफेर करने के लिए तैयार हो तो एक कॉलबैक प्रदान करता है।

onWinLoad सब कुछ लोड होने पर कॉलबैक प्रदान करता है (चित्र आदि)

  • आप जब चाहें इन कार्यों को बुलाया जा सकता है।
  • कई "श्रोताओं" का समर्थन करता है।
  • किसी भी ब्राउज़र में काम करेगा।

0
(function(f){
  if(document.readyState != "loading") f();
  else document.addEventListener("DOMContentLoaded", f);
})(function(){
  console.log("The Document is ready");
});

इससे क्या पता चलता है कि अन्य उत्तर नहीं देते हैं?
dwjohnston

यह एक स्व-बंद क्लोजर का उपयोग करता है (वैश्विक "विंडो" गुंजाइश को आबाद नहीं करता है), यह सभी ब्राउज़र पर काम करता है और बहुत कॉम्पैक्ट है। मैं इसके जैसे कोई अन्य उत्तर नहीं देखता हूं।
डस्टिन पॉसेंट

यह डोम के पहले ही लोड होने के बाद भी काम करता है (जैसे jQuery.ready करता है), जो कि इनमें से अधिकांश उत्तर करने में विफल रहते हैं।
डस्टिन पॉसेंट

0

अधिकांश वैनिला जेएस रेडी फ़ंक्शन उस परिदृश्य पर विचार नहीं करते हैं जहां दस्तावेज़ पहले से लोड होने के बादDOMContentLoaded हैंडलर सेट किया गया है - जिसका अर्थ है कि फ़ंक्शन कभी भी नहीं चलेगा । यह तब हो सकता है जब आप DOMContentLoadedकिसी asyncबाहरी स्क्रिप्ट ( <script async src="file.js"></script>) के भीतर देखें ।

नीचे दिया गया कोड DOMContentLoadedकेवल तभी चेक करता है जब दस्तावेज़ readyStateपहले से ही interactiveया नहीं है complete

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

यदि आप IE aswell का समर्थन करना चाहते हैं:

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!
});

0

मैं बस का उपयोग करें:

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

और document.addEventListener("DOMContentLoaded" //etcबहुत ही शीर्ष उत्तर के विपरीत , यह IE9 के रूप में वापस काम करता है - http://caniuse.com/#search=DOMContendLoaded केवल IE11 के रूप में हाल ही में इंगित करता है।

दिलचस्प है कि मैं setTimeout2009 में इस समाधान पर ठोकर खाई : डोम ओवरकिल की तत्परता के लिए जाँच कर रहा है?, जो शायद थोड़ा बेहतर तरीके से शब्दों में बयां किया जा सकता था, जैसा कि मेरा मतलब था "डोम की तत्परता की जांच करने के लिए विभिन्न रूपरेखाओं के अधिक जटिल दृष्टिकोणों का उपयोग करने के लिए यह ओवरकिल है"।

यह तकनीक क्यों काम करती है, इसके बारे में मेरी सबसे अच्छी व्याख्या यह है कि जब इस तरह के सेटटाइमआउट वाली स्क्रिप्ट पहुंच गई है, तो DOM पार्स होने के बीच में है, इसलिए सेटटाइम के भीतर कोड का निष्पादन तब तक स्थगित हो जाता है जब तक कि ऑपरेशन समाप्त नहीं हो जाता।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.