web-dev-qa-db-fra.com

$ (document) .ready équivalent sans jQuery

J'ai un script qui utilise $(document).ready, mais il n'utilise rien d'autre de jQuery. J'aimerais alléger le problème en supprimant la dépendance jQuery.

Comment puis-je implémenter ma propre fonctionnalité $(document).ready sans utiliser jQuery? Je sais que l'utilisation de window.onload ne sera pas la même chose, car window.onload se déclenche après le chargement de toutes les images, images, etc.

1879
FlySwat

Il existe un remplacement basé sur des normes, DOMContentLoaded, pris en charge par over 98% des navigateurs , mais pas par IE8:

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

la fonction native de jQuery est bien plus compliquée que simplement window.onload, comme illustré ci-dessous.

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

Modifier:

Voici un remplacement viable pour jQuery ready

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

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

ne autre bonne fonction domReady ici extrait de https://stackoverflow.com/a/9899701/175071


Comme la réponse acceptée était très loin d’être complète, j’ai assemblé une fonction "prête" comme jQuery.ready() basée sur la source 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;
})();

Comment utiliser:

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

Je ne suis pas sûr de la fonctionnalité de ce code, mais il a bien fonctionné avec mes tests superficiels. Cela a pris un certain temps et j'espère que vous et les autres pourrez en tirer profit.

PS: Je suggère compiler le.

Ou vous pouvez utiliser http://dustindiaz.com/smallest-domready-ever :

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

ou la fonction native si vous n'avez besoin que de prendre en charge les nouveaux navigateurs (contrairement à prêt pour jQuery, cela ne fonctionnera pas si vous ajoutez ceci après le chargement de la page)

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

Trois options:

  1. Si script est la dernière balise du corps, le DOM sera prêt avant l'exécution de la balise de script.
  2. Lorsque le DOM est prêt, "readyState" passera à "terminé"
  3. Tout mettre sous l'écouteur d'événement 'DOMContentLoaded'

onreadystatechange

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

Source: MDN

DOMContentLoaded

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

Préoccupé par les navigateurs de l'âge de pierre: Allez au code source de jQuery et utilisez le ready une fonction. Dans ce cas, vous n'analysez pas + n'exécutez pas la totalité de la bibliothèque, vous n'en exécutez qu'une très petite partie.

197
KhanSharp

Placez votre <script>/*JavaScript code*/</script> droite avant la fermeture</body> tag.

Certes, cela ne conviendra peut-être pas à tout le monde car il faut changer le fichier HTML plutôt que de faire quelque chose dans le fichier JavaScript à la document.ready, mais quand même ...

85
rob

La solution du pauvre:

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

checkLoad();  

Voir le violon

Ajout de celui-ci, un peu mieux je suppose, propre portée et non récursif

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

Voir le violon

67
Jakob Sternberg

J'utilise ceci:

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

Remarque: cela ne fonctionne probablement qu'avec les navigateurs les plus récents, en particulier ceux-ci: http://caniuse.com/#feat=domcontentloaded

34
Dustin Davis

Vraiment, si vous vous souciez de Internet Explorer 9 + seulement, ce code suffirait pour remplacer jQuery.ready:

    document.addEventListener("DOMContentLoaded", callback);

Si vous vous inquiétez à propos de Internet Explorer 6 et de navigateurs vraiment étranges et rares, cela fonctionnera:

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

Cette question a été posée il y a assez longtemps. Pour tous ceux qui ne voient que cette question, il existe désormais un site appelé "vous n'avez peut-être pas besoin de jquery" qui décompose - par niveau de IE le support requis - toutes les fonctionnalités de jquery et fournit des bibliothèques alternatives plus petites.

Document IE8 script prêt selon vous n'avez peut-être pas besoin de 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();
        });
}
18
chugadie

J'utilisais récemment cela pour un site mobile. Ceci est la version simplifiée de John Resig tirée de "Techniques JavaScript professionnelles". Cela dépend de 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
James

La réponse de jQuery m'a été très utile. Avec un peu de réfractaire, cela répond bien à mes besoins. J'espère que ça aide quelqu'un d'autre.

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 (anciens navigateurs aussi) et une solution simple:

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

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

Affichage de l'alerte dans jsfiddle

10
Pawel

Voici l'extrait de code le plus petit permettant de tester DOM ready et qui fonctionne sur tous les navigateurs (même IE 8):

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

Voir ceci réponse .

9
Antara Roy

Ajoutez simplement ceci au bas de votre page HTML ...

<script>
    Your_Function();
</script>

En effet, les documents HTML sont analysés par le haut en bas.

6
davefrassoni

Il vaut la peine de chercher dans Rock Solid addEvent () et http://www.braksator.com/ comment-faire-votre-propre-jquery .

Voici le code en cas de coupure du site

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

Ce code inter-navigateurs appellera une fonction une fois que le DOM est prêt:

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

Voilà comment cela fonctionne:

  1. La première ligne de domReady appelle la méthode toString de la fonction pour obtenir une représentation sous forme de chaîne de la fonction que vous transmettez et l'encapsule dans une expression qui appelle immédiatement la fonction.
  2. Le reste de domReady crée un élément de script avec l'expression et l'ajoute au body du document.
  3. Le navigateur exécute des balises de script ajoutées à body une fois que le DOM est prêt.

Par exemple, si vous faites ceci: domReady(function(){alert();});, l'élément suivant sera ajouté à l'élément body:

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

Notez que cela ne fonctionne que pour les fonctions définies par l'utilisateur. Ce qui suit ne fonctionnera pas: domReady(alert);

4
Max Heiber

Il est toujours bon d'utiliser des équivalents JavaScript par rapport à jQuery. Une des raisons est une bibliothèque de moins sur laquelle compter et elles sont beaucoup plus rapides que les équivalents jQuery.

Une référence fantastique pour les équivalents jQuery est http://youmightnotneedjquery.com/ .

En ce qui concerne votre question, j'ai pris le code ci-dessous à partir du lien ci-dessus :) Seul bémol, c'est qu'il ne fonctionne qu'avec Internet Explorer 9 et ultérieur.

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

Que diriez-vous de cette solution?

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

Nous avons trouvé une implémentation rapide et compliquée de navigateurs croisés qui pourrait faire l'affaire dans la plupart des cas simples avec une implémentation minimale:

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

Les solutions setTimeout/setInterval présentées ici ne fonctionneront que dans des circonstances spécifiques.

Le problème apparaît en particulier dans les anciennes versions d'Internet Explorer jusqu'à 8.

Les variables affectant le succès de ces solutions setTimeout/setInterval sont les suivantes:

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

le code original (Javascript natif) permettant de résoudre ce problème spécifique est ici:

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

c'est le code à partir duquel l'équipe jQuery a construit son implémentation.

2
Diego Perini

Voici ce que j'utilise, c'est rapide et couvre toutes les bases, je pense; fonctionne pour tout sauf IE <9.

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

Cela semble attraper tous les cas:

  • se déclenche immédiatement si le DOM est déjà prêt (si le DOM n'est pas "en cours de chargement", mais "interactif" ou "complet")
  • si le DOM est toujours en cours de chargement, il configure un écouteur d'événements lorsque le DOM est disponible (interactif).

L'événement DOMContentLoaded est disponible dans IE9 et tout le reste, donc personnellement, je pense que c'est OK pour l'utiliser. Réécrivez la déclaration de la fonction de flèche en une fonction anonyme standard si vous ne transférez pas votre code d'ES2015 à ES5.

Si vous voulez attendre que tous les actifs soient chargés, toutes les images affichées, etc., utilisez plutôt window.onload.

1
Olemak

J'utilise simplement:

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

Et contrairement à document.addEventListener("DOMContentLoaded" //etc comme dans la réponse tout en haut, cela fonctionne aussi loin que IE9 - http://caniuse.com/#search=DOMContentLoaded n'indique que récemment que IE11.

Par exemple, accédez à https://netrenderer.com/index.php , choisissez Internet Explorer 9 dans le menu déroulant, entrez https://dexygen.github.io/blog/oct -2017/jekyll/catégories-jekyll/liquid-templates/2017/10/22/comment-jekyll-builds-site-categories.html et cliquez sur "Render", et vous verrez quelque chose qui ressemble à la capture d'écran à la bas de ce post.

Voir le code Javascript suivant que j'utilise dans l'en-tête pour manipuler à mon goût le style du thème "hacker" de Jekyll - vous pouvez notamment faire référence au bloc if (location.pathname !== rootPath) pour voir comment je l'insère dans la variable Home et Blog Home liens affichés par IE9 sur le site NetRenderer.

Fait intéressant, je suis tombé sur cette solution setTimeout en 2009: Est-ce que la vérification de l'état de préparation du DOM est excessive? , qui aurait probablement pu être libellé légèrement mieux, comme je voulais dire par l'utilisation de plusieurs cadres plus approches compliquées.

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

Si vous n'avez pas à prendre en charge de très vieux navigateurs, voici une façon de le faire même si votre script externe est chargé avec l'attribut 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");
});
1
user4617883

La fonction ready dans jQuery fait un certain nombre de choses. Franchement, je ne vois pas l'intérêt de le remplacer à moins que votre site Web produise des résultats étonnamment limités. jQuery est une jolie bibliothèque minuscule, qui gère toutes sortes de choses inter-navigateurs dont vous aurez besoin plus tard.

Quoi qu'il en soit, il n'y a aucun intérêt à le poster ici, ouvrez simplement jQuery et regardez la méthode bindReady.

Il commence par appeler document.addEventListener("DOMContentLoaded") ou document.attachEvent('onreadystatechange') en fonction du modèle d’événement, puis continue à partir de là.

0
tnyfst

Pour IE9 +:

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

La plupart des fonctions Vanilla JS Ready ne prennent PAS en compte le scénario dans lequel le gestionnaire DOMContentLoaded est défini après le document est déjà chargé - ce qui signifie que la fonction ne sera jamais exécutée. Cela peut arriver si vous recherchez DOMContentLoaded dans un script externe async (<script async src="file.js"></script>).

Le code ci-dessous recherche DOMContentLoaded uniquement si le document readyState du document n'est pas déjà interactive ou complete.

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

Si vous voulez supporter 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
Malvoz

Si vous chargez jQuery près du bas de BODY, mais rencontrez des problèmes avec le code qui écrit jQuery (<func>) ou jQuery (document) .ready (<func>), consultez jqShim on Github.

Plutôt que de recréer sa propre fonction de préparation de document, il conserve les fonctions jusqu'à ce que jQuery soit disponible, puis continue avec jQuery comme prévu. Pour déplacer jQuery au bas du corps, vous devez accélérer le chargement de la page. Vous pouvez toujours le faire en ajoutant le jqShim.min.js dans la tête de votre modèle.

J'ai fini par écrire ce code pour faire en sorte que tous les scripts de WordPress soient déplacés vers le pied de page, et seul ce code shim se trouve maintenant directement dans l'en-tête.

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 fournit un rappel lorsque le dom HTML est prêt à accéder/analyser/manipuler pleinement.

onWinLoad fournit un rappel lorsque tout est chargé (images, etc.)

  • Ces fonctions peuvent être appelées à tout moment.
  • Prend en charge plusieurs "auditeurs".
  • Travaillera dans n'importe quel navigateur.
0
Jakob Sternberg

Essaye ça:

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

Cette approche est le moyen le plus court auquel je puisse penser.

La solution basée sur l'événement DOMContentLoaded ne fonctionne que si le script est chargé avant le document, tandis que la vérification paresseuse suggérée ici garantit que le code est toujours exécuté, même dans les scripts chargés ultérieurement de manière dynamique, exactement comme le document prêt de JQuery.

Ce code est compatible avec tous les navigateurs (y compris certains anciens, jusqu'à IE6 et Safari pour 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