Pertanyaan $ (dokumen). sudah setara tanpa jQuery


Saya memiliki skrip yang menggunakan $(document).ready, tetapi tidak menggunakan apa pun dari jQuery. Saya ingin meringankannya dengan menghapus ketergantungan jQuery.

Bagaimana saya bisa menerapkan sendiri $(document).ready fungsionalitas tanpa menggunakan jQuery? Saya tahu bahwa menggunakan window.onload tidak akan sama, seperti window.onload setelah semua gambar, bingkai, dll. telah dimuat.


1620
2018-04-28 21:51


asal


Jawaban:


Ada pengganti berbasis standar,DOMContentLoaded yang didukung oleh lebih 98% dari browser, meskipun tidak IE8:

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

fungsi asli jQuery jauh lebih rumit daripada hanya window.onload, seperti yang digambarkan di bawah ini.

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

1048
2018-04-28 21:59



Edit:

Berikut ini adalah pengganti yang layak untuk jQuery siap

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

Diambil dari https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/


Karena jawaban yang diterima sangat jauh dari lengkap, saya menggabungkan fungsi "siap" seperti jQuery.ready() berdasarkan sumber 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;
})();

Bagaimana cara menggunakan:

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

Saya tidak yakin seberapa fungsional kode ini, tetapi bekerja dengan baik dengan tes dangkal saya. Ini memakan waktu cukup lama, jadi saya harap Anda dan orang lain dapat memperoleh manfaat darinya.

PS: Saya sarankan kompilasi saya t.

Atau Anda bisa menggunakannya http://dustindiaz.com/smallest-domready-ever:

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

atau fungsi asli jika Anda hanya perlu mendukung browser baru (Tidak seperti jQuery siap, ini tidak akan berjalan jika Anda menambahkan ini setelah halaman telah dimuat)

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

290
2017-08-13 20:52



Tiga opsi:

  1. Jika script adalah tag terakhir dari tubuh, DOM akan siap sebelum tag skrip dieksekusi
  2. Ketika DOM siap, "readyState" akan berubah menjadi "selesai"
  3. Taruh semuanya di bawah pendengar acara 'DOMContentLoaded'

onreadystatechange

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

Sumber: MDN

DOMContentLoaded

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

Khawatir tentang browser zaman batu: Pergi ke kode sumber jQuery dan gunakan ready fungsi. Dalam hal ini Anda tidak melakukan parsing + mengeksekusi seluruh pustaka yang Anda lakukan hanya sebagian kecil darinya.


184
2017-09-12 22:33



Tempatkan Anda <script>/*JavaScript code*/</script> kanan sebelum penutupan  </body> menandai.

Diakui, ini mungkin tidak sesuai dengan tujuan semua orang karena membutuhkan perubahan file HTML daripada hanya melakukan sesuatu dalam file JavaScript ala document.ready, tetapi tetap saja...


81
2017-12-07 16:46



Solusi orang miskin:

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

checkLoad();  

Lihat Fiddle

Ditambahkan satu ini, sedikit lebih baik saya kira, lingkup sendiri, dan non rekursif

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

Lihat Fiddle


67
2017-08-04 18:13



Saya menggunakan ini:

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

Catatan: Ini mungkin hanya berfungsi dengan browser yang lebih baru, terutama ini: http://caniuse.com/#feat=domcontentloaded


31
2017-12-23 19:14



Sungguh, jika Anda peduli Internet Explorer 9+ hanya, kode ini cukup untuk menggantikan jQuery.ready:

    document.addEventListener("DOMContentLoaded", callback);

Jika kamu khawatir Internet Explorer 6 dan beberapa browser yang benar-benar aneh dan langka, ini akan berfungsi:

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

19
2017-11-07 07:45



Pertanyaan ini ditanyakan cukup lama. Bagi siapa saja yang melihat pertanyaan ini, sekarang ada situs yang disebut "Anda mungkin tidak perlu jquery"  yang rusak - oleh tingkat dukungan IE yang diperlukan - semua fungsi jquery dan menyediakan beberapa alternatif, perpustakaan yang lebih kecil.

Dokumen IE8 siap script sesuai Anda mungkin tidak perlu 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();
        });
}

15
2018-02-16 14:15