it-swarm.com.de

$ (document) .ready entspricht ohne jQuery

Ich habe ein Skript, das $(document).ready verwendet, aber nichts anderes von jQuery. Ich möchte es aufhellen, indem ich die jQuery-Abhängigkeit entferne.

Wie kann ich meine eigene $(document).ready -Funktionalität implementieren, ohne jQuery zu verwenden? Ich weiß, dass die Verwendung von window.onload nicht identisch ist, da window.onload ausgelöst wird, nachdem alle Bilder, Rahmen usw. geladen wurden.

1879
FlySwat

Es gibt einen standardbasierten Ersatz, DOMContentLoaded, der von über 98% der Browser unterstützt wird, jedoch nicht von IE8:

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

die native Funktion von jQuery ist viel komplizierter als nur window.onload (siehe Abbildung unten).

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 );
}
1295
Chad Grant

Bearbeiten:

Hier ist ein praktikabler Ersatz für jQuery bereit

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

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

Eine weitere gute domReady-Funktion hier entnommen aus https://stackoverflow.com/a/9899701/175071


Da die akzeptierte Antwort bei weitem nicht vollständig war, habe ich eine "Fertig" -Funktion wie jQuery.ready() zusammengefügt, die auf der Quelle von jQuery 1.6.2 basiert:

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

Wie benutzt man:

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

Ich bin nicht sicher, wie funktionsfähig dieser Code ist, aber er hat bei meinen oberflächlichen Tests einwandfrei funktioniert. Das hat eine Weile gedauert, also hoffe ich, dass Sie und andere davon profitieren können.

PS .: Ich schlage vor Kompilieren es.

Oder Sie können http://dustindiaz.com/smallest-domready-ever verwenden:

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

oder die native Funktion, wenn Sie nur die neuen Browser unterstützen müssen (im Gegensatz zu jQuery ready wird dies nicht ausgeführt, wenn Sie dies hinzufügen, nachdem die Seite geladen wurde)

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

Drei Möglichkeiten:

  1. Wenn script das letzte Tag des Körpers ist, wäre das DOM bereit, bevor das Skript-Tag ausgeführt wird
  2. Wenn das DOM fertig ist, ändert sich "readyState" in "complete"
  3. Stellen Sie alles unter den Ereignis-Listener 'DOMContentLoaded'

onreadystatechange

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

Quelle: MDN

DOMContentLoaded

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

Betroffen über Steinzeit-Browser: Gehen Sie zum jQuery-Quellcode und verwenden Sie das ready Funktion. In diesem Fall wird nicht die gesamte Bibliothek analysiert und ausgeführt, sondern nur ein sehr kleiner Teil davon.

197
KhanSharp

Platzieren Sie Ihr <script>/*JavaScript code*/</script> rechts vor dem Schließen</body> -Tag.

Zugegeben, dies ist möglicherweise nicht für alle Zwecke geeignet, da die HTML-Datei geändert werden muss, anstatt nur etwas in der JavaScript-Datei a la document.ready zu tun, aber dennoch ...

85
rob

Die Lösung des armen Mannes:

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

checkLoad();  

Geige ansehen

Fügte dieses hinzu, ein bisschen besser, denke ich, eigener Bereich und nicht rekursiv

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

Geige ansehen

67
Jakob Sternberg

Ich benutze das:

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

Hinweis: Dies funktioniert wahrscheinlich nur mit neueren Browsern, insbesondere diesen: http://caniuse.com/#feat=domcontentloaded

34
Dustin Davis

Wenn Sie sich nur für Internet Explorer 9 + interessieren, würde dieser Code ausreichen, um jQuery.ready zu ersetzen:

    document.addEventListener("DOMContentLoaded", callback);

Wenn Sie sich Sorgen um Internet Explorer 6 und einige wirklich seltsame und seltene Browser machen, funktioniert Folgendes:

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

Diese Frage wurde vor langer Zeit gestellt. Für alle, die gerade diese Frage sehen, gibt es jetzt eine Site mit dem Namen "Sie benötigen möglicherweise keine Abfrage" , die - nach dem Grad der erforderlichen IE -Unterstützung - die gesamte Funktionalität von jquery und aufschlüsselt bietet einige alternative, kleinere Bibliotheken.

IE8 document ready script gemäß möglicherweise benötigen Sie jquery nicht

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

Ich habe dies kürzlich für eine mobile Website verwendet. Dies ist die vereinfachte Version von John Resig aus "Pro JavaScript Techniques". Es hängt von addEvent ab.

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
James

Die jQuery-Antwort war für mich ziemlich nützlich. Mit ein wenig feuerfestem Material passt es gut zu meinen Bedürfnissen. Ich hoffe es hilft jemand anderem.

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 )
}
11
Miere

Cross-Browser (auch alte Browser) und eine einfache Lösung:

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

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

Zeige Alarm in jsfiddle

10
Pawel

Hier ist das kleinste Codefragment zum Testen von DOM ready , das in allen Browsern funktioniert (sogar in IE 8):

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

Siehe dies Antwort .

9
Antara Roy

Fügen Sie dies einfach am Ende Ihrer HTML-Seite hinzu ...

<script>
    Your_Function();
</script>

Weil HTML-Dokumente von oben nach unten analysiert werden.

6
davefrassoni

Es lohnt sich in Rock Solid addEvent () und http://www.braksator.com/ How-to-Make-Your-Own-JQuery .

Hier ist der Code für den Fall, dass die Website ausfällt

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
Ben

Dieser browserübergreifende Code ruft eine Funktion auf, sobald das DOM bereit ist:

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

So funktioniert das:

  1. In der ersten Zeile von domReady wird die Methode toString der Funktion aufgerufen, um eine Zeichenfolgendarstellung der von Ihnen übergebenen Funktion abzurufen und sie in einen Ausdruck zu setzen, der die Funktion sofort aufruft.
  2. Der Rest von domReady erstellt ein Skriptelement mit dem Ausdruck und hängt es an die body des Dokuments an.
  3. Der Browser führt Skript-Tags aus, die an body angehängt sind, nachdem das DOM fertig ist.

Wenn Sie dies beispielsweise tun: domReady(function(){alert();});, wird Folgendes an das Element body angehängt:

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

Beachten Sie, dass dies nur für benutzerdefinierte Funktionen funktioniert. Folgendes funktioniert nicht: domReady(alert);

4
Max Heiber

Es ist immer gut, JavaScript-Entsprechungen im Vergleich zu jQuery zu verwenden. Ein Grund dafür ist, dass eine Bibliothek weniger benötigt wird und diese viel schneller ist als die jQuery-Entsprechungen.

Eine fantastische Referenz für jQuery-Entsprechungen ist http://youmightnotneedjquery.com/ .

Was Ihre Frage betrifft, habe ich den folgenden Code aus dem obigen Link genommen: :) Nur, dass dies nur mit Internet Explorer 9 und höher funktioniert.

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

Wie wäre es mit dieser Lösung?

// 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
mike

Wir haben eine schnelle und schmutzige Cross-Browser-Implementierung gefunden, die für die meisten einfachen Fälle mit einer minimalen Implementierung ausreichen kann:

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

Die hier vorgestellten Lösungen setTimeout/setInterval funktionieren nur unter bestimmten Umständen.

Das Problem tritt insbesondere bei älteren Internet Explorer-Versionen bis 8 auf.

Die Variablen, die den Erfolg dieser setTimeout/setInterval-Lösungen beeinflussen, sind:

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

der ursprüngliche (native Javascript) Code zur Behebung dieses Problems befindet sich hier:

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

dies ist der Code, aus dem das jQuery-Team seine Implementierung erstellt hat.

2
Diego Perini

Hier ist, was ich benutze, es ist schnell und deckt alle Grundlagen ab, die ich denke; funktioniert für alles außer IE <9.

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

Dies scheint alle Fälle zu erfassen:

  • wird sofort ausgelöst, wenn das DOM bereits bereit ist (wenn das DOM nicht "geladen", sondern "interaktiv" oder "abgeschlossen" ist)
  • wenn das DOM noch geladen ist, richtet es einen Ereignis-Listener ein, wenn das DOM verfügbar ist (interaktiv).

Das DOMContentLoaded-Ereignis ist im IE9 und in allen anderen Bereichen verfügbar. Ich persönlich halte es für in Ordnung, dies zu verwenden. Schreiben Sie die Pfeilfunktionsdeklaration in eine normale anonyme Funktion um, wenn Sie Ihren Code nicht von ES2015 auf ES5 transpilieren.

Wenn Sie warten möchten, bis alle Assets geladen sind, alle Bilder angezeigt werden usw., verwenden Sie stattdessen window.onload.

1
Olemak

Ich benutze einfach:

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

Und im Gegensatz zu document.addEventListener("DOMContentLoaded" //etc wie in der allerhöchsten Antwort funktioniert es bis zu IE9 - http://caniuse.com/#search=DOMContentLoaded zeigt nur an, dass es sich um IE11 handelt.

Gehen Sie zum Beispiel zu https://netrenderer.com/index.php , wählen Sie Internet Explorer 9 aus der Dropdown-Liste aus und geben Sie https://dexygen.github.io/blog/oct) ein -2017/jekyll/jekyll-kategorien/liquid-templates/2017/10/22/wie-jekyll-baut-site-kategorien.html und klicken Sie auf "Rendern", und Sie werden etwas sehen, das dem Screenshot auf der ähnelt Ende dieses Beitrags.

Siehe den folgenden Javascript-Code, den ich in der Kopfzeile verwende, um den Stil des Jekyll-Themas "Hacker" nach meinen Wünschen zu ändern. Insbesondere können Sie auf den Block if (location.pathname !== rootPath) verweisen, um zu sehen, wie ich die Links Home und Blog Home einfüge , die von IE9 auf der NetRenderer-Site angezeigt werden.

Interessanterweise bin ich im Jahr 2009 auf diese setTimeout-Lösung gestoßen: Wird auf die Bereitschaft des DOM-Overkills geprüft? , die wahrscheinlich etwas besser formuliert werden könnte, da ich die komplizierteren Ansätze verschiedener Frameworks verwendet habe.

setTimeout(function() {//delay execution until after dom is parsed
    var containerEls = document.getElementsByClassName('container');
    var headingEl = containerEls[0].getElementsByTagName('h1')[0];
    var headerEl = document.getElementsByTagName('header')[0];
    var downloadsSectionEl = document.getElementById('downloads');
    var rootPath = "/";
    var blogRootPath = "/blog/";

    containerEls[0].style.maxWidth = '800px';
    containerEls[1].style.maxWidth = '800px';
    headingEl.style.margin = '0';
    headerEl.style.marginBottom = '7px';
    downloadsSectionEl.style.margin = '0';

    if (location.pathname !== rootPath) {
        downloadsSectionEl.appendChild(generateNavLink('Home', rootPath));
        if (location.pathname !== blogRootPath) {
            downloadsSectionEl.appendChild(document.createTextNode(' | '));
            downloadsSectionEl.appendChild(generateNavLink('Blog Home', blogRootPath));
        }
    }

    function generateNavLink(linkText, hrefPath) {
        var navLink = document.createElement('a');
        var linkTextNode = document.createTextNode(linkText);
        navLink.setAttribute('href', hrefPath);
        navLink.appendChild(linkTextNode);
        return navLink;
    }
});

dexygen.github.io on IE9

1
George Jempty

Wenn Sie keine sehr alten Browser unterstützen müssen, können Sie dies auch tun, wenn Ihr externes Skript mit dem Attribut async geladen ist:

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");
});
1
user4617883

Die Bereitschaftsfunktion in jQuery führt eine Reihe von Dingen aus. Ehrlich gesagt sehe ich keinen Grund, es zu ersetzen, es sei denn, Sie haben eine erstaunlich kleine Ausgabe von Ihrer Website. jQuery ist eine ziemlich kleine Bibliothek, die alle Arten von browserübergreifenden Dingen verarbeitet, die Sie später benötigen.

Wie auch immer, es hat wenig Sinn, es hier zu posten. Öffnen Sie einfach jQuery und schauen Sie sich die bindReady -Methode an.

Es beginnt mit dem Aufruf von document.addEventListener("DOMContentLoaded") oder document.attachEvent('onreadystatechange'), je nach Ereignismodell, und geht von dort aus weiter.

0
tnyfst

Für IE9 +:

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

Die meisten Vanilla JS Ready-Funktionen berücksichtigen NICHT das Szenario, in dem der Handler DOMContentLoaded gesetzt ist nach das Dokument ist bereits geladen - was bedeutet, dass die Funktion nie ausgeführt wird. Dies kann passieren, wenn Sie nach DOMContentLoaded in einem async externen Skript (<script async src="file.js"></script>) suchen.

Der folgende Code prüft auf DOMContentLoaded nur, wenn das readyState des Dokuments nicht bereits interactive oder complete ist.

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

Wenn Sie auch IE unterstützen möchten:

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
Malvoz

Wenn Sie jQuery im unteren Bereich von BODY laden, jedoch Probleme mit Code haben, der jQuery (<func>) oder jQuery (document) .ready (<func>) ausgibt, lesen Sie jqShim on Github.

Anstatt eine eigene dokumentenfertige Funktion neu zu erstellen, behält sie einfach die Funktionen bei, bis jQuery verfügbar ist, und fährt dann erwartungsgemäß mit jQuery fort. Der Zweck des Verschiebens von jQuery an den unteren Rand des Texts besteht darin, das Laden der Seite zu beschleunigen, und Sie können dies dennoch erreichen, indem Sie die Datei jqShim.min.js in den Kopf Ihrer Vorlage einfügen.

Am Ende habe ich diesen Code geschrieben, um alle Skripte in WordPress in die Fußzeile zu verschieben, und nur dieser Shim-Code befindet sich jetzt direkt in der Kopfzeile.

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

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

onDocReady liefert einen Rückruf, wenn die HTML-Domäne zum vollständigen Zugriff/Parsen/Manipulieren bereit ist.

onWinLoad liefert einen Rückruf, wenn alles geladen ist (Bilder etc)

  • Diese Funktionen können jederzeit aufgerufen werden.
  • Unterstützt mehrere "Listener".
  • Funktioniert in jedem Browser.
0
Jakob Sternberg

Versuche dies:

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

Dieser Ansatz ist der kürzeste Weg, den ich mir vorstellen kann.

Die auf dem Ereignis DOMContentLoaded basierende Lösung funktioniert nur, wenn das Skript vor dem Dokument geladen wird, während die hier vorgeschlagene verzögerte Prüfung sicherstellt, dass der Code auch in später dynamisch geladenen Skripten immer genau so ausgeführt wird, wie das Dokument von JQuery bereit ist.

Dieser Code ist mit allen Browsern kompatibel (einschließlich einiger älterer Versionen bis hinunter zu IE6 und Safari für Windows).

(function ready() {
    if (!document.body) {setTimeout(ready, 50); return;}
    // Document is ready here
})();
0
Javier Rey
(function(f){
  if(document.readyState != "loading") f();
  else document.addEventListener("DOMContentLoaded", f);
})(function(){
  console.log("The Document is ready");
});
0
Dustin Poissant