Requirejs le plugin domReady vs Jquery $ (document) .ready ()?

100

J'utilise RequireJS et j'ai besoin d'initialiser quelque chose sur DOM prêt. Maintenant, RequireJS fournit le domReadyplugin , mais nous avons déjà jQuery $(document).ready(), qui m'est disponible puisque j'ai besoin de jQuery.

J'ai donc deux options:

  1. Utilisez le domReadyplugin:

    require(['domReady'], function (domReady) {
        domReady(function () {
            // Do my stuff here...
        });
    });
  2. Utilisez $(document).ready():

    $(document).ready(function() {
        // Do my stuff here...
    });

Lequel devrais-je choisir et pourquoi?

Les deux options semblent fonctionner comme prévu. Je n'ai pas confiance en celui de jQuery car RequireJS fait sa magie; c'est-à-dire que RequireJS ajoutera dynamiquement des scripts, je crains que DOM ready ne se produise avant que tous les scripts demandés dynamiquement ne soient chargés. Considérant que, RequireJS ajoutera une charge sur JS supplémentaire juste pour domReadyquand jQuery est déjà requis.

Des questions

  • Pourquoi RequireJS fournit-il un domReadyplugin alors que nous pouvons avoir jQuery $(document).ready();? Je ne vois aucun avantage à inclure une autre dépendance.
  • Si c'est juste pour répondre à un besoin, pourquoi ne pas en fournir un pour AJAX inter-navigateur?

Pour autant que je sache, un module qui nécessite domReadyne sera pas récupéré ou exécuté une fois le document prêt, et vous pouvez faire la même chose en demandant jQuery:

require(['jQuery'], function ($) {
    $(document).ready(function () {
        // Do my stuff here...
    });
});

Pour être plus clair sur ma question: quelle est la différence entre exiger domReadyou jQuery?

Yugal Jindle
la source
4
I am not confident in jquery's dom readyJe veux le marquer comme offensif:p
Dakait
3
Le dom ready de jQuery est parfaitement fiable, même sur IE. Des millions de personnes l'utilisent chaque jour sans le savoir ;-)
John Dvorak
1
Contrôlez-vous où scriptvont vos balises, ou écrivez-vous une bibliothèque / un plug-in que d'autres personnes utiliseront (et qui contrôlent donc l'emplacement des scriptbalises dans le balisage)?
TJ Crowder
3
Oh mon Dieu ... lisez-le avec le contexte complet. I am not confident in jquery's dom ready because requirejs is doing its magic.Depuis, require encapsule jquery dans une portée locale limitée. Ce n'est pas la question. (en ce qui concerne la question).
Yugal Jindle
1
Merci, @TJCrowder pour la modification.
Yugal Jindle

Réponses:

91

Il semble que tous les points clés aient déjà été atteints, mais quelques détails sont passés entre les mailles du filet. Principalement:

domReady

C'est à la fois un plugin et un module. Si vous l'incluez dans le tableau des exigences avec une fin, !votre module ne s'exécutera pas tant qu'il ne sera pas "sûr" d'interagir avec le DOM:

define(['domReady!'], function () {
    console.info('The DOM is ready before I happen');
});

Notez que le chargement et l'exécution sont différents; vous voulez que tous vos fichiers se chargent le plus tôt possible, c'est l'exécution du contenu qui est sensible au temps.

Si vous omettez le !, c'est juste un module normal qui se trouve être une fonction, qui peut prendre un rappel qui ne s'exécutera pas avant que le DOM puisse interagir en toute sécurité:

define(['domReady'], function (domReady) {
    domReady(function () {
        console.info('The DOM is ready before I happen');
    });
    console.info('The DOM might not be ready before I happen');        
});

Avantage lors de l'utilisation de domReady en tant que plugin

Le code qui dépend d'un module qui dépend à son tour domReady!a un avantage très important: il n'a pas besoin d'attendre que le DOM soit prêt!

Disons que nous avons un bloc de code, A, qui dépend d'un module, B, qui dépend de domReady!. Le module B ne terminera pas le chargement avant que le DOM ne soit prêt. À son tour, A ne fonctionnera pas avant que B ne soit chargé.

Si vous deviez utiliser domReadycomme module normal dans B, il serait également nécessaire que A dépende domReady, ainsi que d'encapsuler son code dans un domReady()appel de fonction.

En outre, cela signifie que domReady!bénéficie du même avantage sur $(document).ready().

Re les différences entre domReady et $ (document) .ready ()

Les deux détectent si / quand le DOM est prêt essentiellement de la même manière.

Re peur de tirer jQuery au mauvais moment

jQuery lancera tout rappel prêt même si le DOM se charge avant jQuery (votre code ne devrait pas se soucier de ce qui se produit en premier).

fncomp
la source
1
Magnifique, c'est ce que je cherchais. Raisonnable, bien pris en charge.
Yugal Jindle
Heureux de pouvoir aider :-)
fncomp
@YugalJindle Il manque quelque chose pour la prime? :)
fncomp
J'étais juste en train de tester ce que vous avez écrit - c'est parti!
Yugal Jindle
En regardant le code du plugin domReady ( github.com/requirejs/domReady/blob/master/domReady.js ), je ne vois aucune raison pour laquelle vous devez le charger en tant que «domReady! au lieu de «domReady» - pourriez-vous m'indiquer le morceau de code qui cause ce changement de comportement?
Jez
20

Une tentative pour répondre à votre question principale:

Pourquoi requirejsfournit-il un domReadyplugin alors que nous pouvons avoir des jquery $(document).ready();?

Ils font deux choses différentes, vraiment. La domReadydépendance de RequireJS signifie que ce module nécessite que le DOM soit complètement chargé avant de pouvoir être exécuté (et peut donc être trouvé dans n'importe quel nombre de modules de votre application si vous le souhaitez), alors $(document).ready()qu'il déclenche à la place ses fonctions de rappel lorsque le DOM est chargement a été fait.

La différence peut sembler subtile, mais pensez à ceci: j'ai un module qui doit être couplé au DOM d'une manière ou d'une autre, donc je peux soit en dépendre domReadyet le coupler au moment de la définition du module, soit mettre un $(document).ready()à la fin de celui-ci avec un rappel vers une fonction init pour le module. J'appellerais la première approche plus propre.

En attendant, si j'ai un événement qui doit se produire juste au moment où le DOM est prêt, l' $(document).ready()événement serait le choix, car cela ne dépend pas en particulier du chargement de modules par RequireJS, à condition que les dépendances du code que vous l'appelant de sont satisfaits.

Il est également intéressant de noter que vous n'utilisez pas nécessairement RequireJS avec jQuery. Tout module de bibliothèque qui a besoin d'un accès DOM (mais ne repose pas sur jQuery) serait alors toujours utile en utilisant domReady.

Gert Sønderby
la source
domReadyn'est pas une dépendance pour requirejs. Ce serait une dépendance pour le code si vous utilisez domReadypour l'événement DocumentReady. De plus, vous semblez déroutant.
Yugal Jindle
1
Excellente réponse, et un indice important sur les subtilités que de nombreux développeurs ne réalisent souvent pas (moi y compris ;-)).
Golo Roden
1
Yugal, je parlais de domReadydépendance, car c'est ainsi qu'il est utilisé. Pas en tant que dépendance de RequireJS, mais du module où il est utilisé. Je devrais peut-être clarifier cela dans mon texte, avez-vous des suggestions pour savoir comment?
Gert Sønderby
Veuillez consulter la mise à jour 2 sur la question. Peut-être ne sommes-nous pas sur la même longueur d'onde.
Yugal Jindle
Yugal, et si vous utilisez MooTools? Qooxdoo? Quelque chose de pas jQuery? RequireJS n'est pas marié à jQuery, bien qu'ils fonctionnent vraiment bien ensemble.
Gert Sønderby
6

Répondre à vos balles par ordre d'apparition:

  • Ils accomplissent tous les deux la même chose
  • Si vous avez des réserves sur jquery pour une raison quelconque, utilisez domReady
  • Correct, alors utilisez simplement jQuery
  • Parce que tout le monde n'utilise pas jQuery
  • Je suis d'accord, utilisez simplement jQuery
  • Les plugins par définition «alimentent un besoin».
  • Cross Browser ajax n'est pas une chose. Cross Domain? Il y en a probablement, et s'il n'y en a pas, il n'est pas nécessaire de se nourrir.
  • , -, -, - D'accord

En fin de compte, vous y réfléchissez trop. C'est un mécanisme pour exécuter javascript sur domReady. Si vous n'aviez pas jQuery, je recommanderais le plugin domReady. Puisque vous avez jQuery, ne chargez pas plus de scripts pour faire quelque chose qui est déjà disponible.

Mise à jour de la clarté

Le plugin domReady collecte les fonctions à appeler lorsque le document est «prêt». S'il est déjà chargé, ils s'exécutent immédiatement.

JQuery collecte des fonctions et lie un objet différé au dom étant «prêt». Lorsque le dom est prêt, l'objet différé sera résolu et les fonctions se déclencheront. Si le dom est déjà «prêt», alors le différé sera déjà résolu et la fonction s'exécutera immédiatement.

Cela signifie qu'en fait, ils font exactement la même chose.

Awbergs
la source
0

Après quelques essais avec requirejs avec plusieurs modules, je suggère d'utiliser domReady .

J'ai remarqué que la fonction associée à $ (document) .ready (...) n'est pas appelée lorsque plusieurs modules sont chargés par requirejs. Je soupçonne que dom se prépare avant que tout le code requirejs ne soit exécuté et que le gestionnaire de rappel prêt jquery soit appelé avant qu'il ne soit lié avec la fonction définie par l'utilisateur, c'est-à-dire dans le code du module principal.

require(['jquery',
    'underscore',
    'text!some_template.html',
    './my_module_1',
    './my_module_2',
    'domReady',
    'other_dependency_1',
    'other_dependency_2'
    ], function($, _, someTemplate, myModule1, myModule2, domReady) {

    $(document).ready(function() {
        console.info('This might never be executed.'); 
        console.info('Dom might get ready before requirejs would load modules.');
    });

    domReady(function () {
        console.info('This runs when the dom gets ready and modules are loaded.');
    });
});
Marcin Nowakowski
la source
1
Je doute que, si vous avez tous les modules dans votre liste de dépendances, tous seront récupérés et mis en mémoire. post que jquery collecte les instances dom.ready avant l'exécution.
Yugal Jindle
Si le DOM est déjà prêt, le rappel pour $(document).readys'exécutera immédiatement.
Danyal Aytekin
-1

J'ai trouvé que je le fais dans le cadre de l'entrée principale afin que tout mon javascript soit garanti que le DOM est prêt et que jquery est chargé. Je ne sais pas à quel point c'est génial, alors soyez les bienvenus, mais voici mon main.js:

require(['domReady!'], function(domReady){
    console.log('dom is ready');
    require(['jquery', 'bootstrap'], function(){
        console.log('jquery loaded');
        require(['app'], function(app){
            console.log('app loaded');
        });
    });
});
Bil Simser
la source