Requirejs domReady Plugin vs Jquery $ (Dokument) .ready ()?

100

Ich verwende RequireJS und muss etwas auf DOM bereit initialisieren. Jetzt stellt RequireJS das domReadyPlugin zur Verfügung , aber wir haben bereits jQuery's $(document).ready(), das mir zur Verfügung steht, da ich jQuery benötigt habe.

Ich habe also zwei Möglichkeiten:

  1. Verwenden Sie das domReadyPlugin:

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

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

Welches soll ich wählen und warum?

Beide Optionen scheinen wie erwartet zu funktionieren. Ich bin nicht zuversichtlich in die jQuery, weil RequireJS seine Magie tut; Das heißt, da RequireJS Skripte dynamisch hinzufügt, mache ich mir Sorgen, dass DOM-fähig sein könnte, bevor alle dynamisch angeforderten Skripte geladen werden. RequireJS wird zusätzliche JS nur dann belasten, domReadywenn ich bereits jQuery benötigt habe.

Fragen

  • Warum stellt RequireJS ein domReadyPlugin zur Verfügung, wenn wir jQuery's haben können $(document).ready();? Ich sehe keinen Vorteil darin, eine andere Abhängigkeit aufzunehmen.
  • Wenn es nur darum geht, einen Bedarf zu decken, warum nicht einen für Cross-Browser-AJAX bereitstellen?

Soweit ich weiß, wird ein Modul, das benötigt domReadywird, nicht abgerufen oder ausgeführt, nachdem das Dokument fertig ist, und Sie können das Gleiche auch mit jQuery tun:

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

Um meine Frage klarer zu formulieren: Was ist der Unterschied zwischen dem Erfordernis domReadyoder jQuery?

Yugal Jindle
quelle
4
I am not confident in jquery's dom readyIch möchte es als anstößig markieren:p
Dakait
3
jQuerys Dom Ready ist auch im IE absolut zuverlässig. Millionen von Menschen benutzen es jeden Tag ohne es zu wissen ;-)
John Dvorak
1
Haben Sie die Kontrolle darüber, wohin Ihre scriptTags gehen, oder schreiben Sie eine Bibliothek / ein Plug-In, die / das andere Benutzer verwenden (und damit die Position der scriptTags im Markup kontrollieren )?
TJ Crowder
3
Oh Gott .. lies es mit dem vollen Kontext. I am not confident in jquery's dom ready because requirejs is doing its magic.Da ist erforderlich, Kapselung in begrenztem lokalen Bereich zu kapseln. Das ist nicht der Punkt. (soweit es die Frage betrifft).
Yugal Jindle
1
Danke, @TJCrowder für die Bearbeitung.
Yugal Jindle

Antworten:

91

Es scheint, als ob alle wichtigen Punkte bereits getroffen wurden, aber ein paar Details fielen durch die Risse. Hauptsächlich:

domReady

Es ist sowohl ein Plugin als auch ein Modul. Wenn Sie es in das Anforderungsarray mit einem Trailing aufnehmen, wird !Ihr Modul erst ausgeführt, wenn die Interaktion mit dem DOM "sicher" ist:

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

Beachten Sie, dass das Laden und Ausführen unterschiedlich ist. Wenn Sie möchten, dass alle Ihre Dateien so schnell wie möglich geladen werden, ist die Ausführung des Inhalts zeitkritisch.

Wenn Sie das weglassen !, handelt es sich nur um ein normales Modul, das zufällig eine Funktion ist, die einen Rückruf annehmen kann, der nicht ausgeführt wird, bevor das DOM sicher interagieren kann:

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

Vorteil bei Verwendung von domReady als Plugin

Code, der von einem Modul abhängt, von dem wiederum abhängt domReady! hat einen sehr bedeutenden Vorteil: Er muss nicht warten, bis das DOM bereit ist!

Angenommen, wir haben einen Codeblock A, der von einem Modul abhängt, B, der davon abhängt domReady! . Modul B wird erst geladen, wenn das DOM bereit ist. A wird wiederum nicht ausgeführt, bevor B geladen wurde.

Wenn Sie es domReadyals reguläres Modul in B verwenden würden, müsste A auch davon abhängen domReadyund seinen Code in einen domReady()Funktionsaufruf einschließen.

Darüber hinaus bedeutet dies, domReady!dass derselbe Vorteil gegenüber $(document).ready().

Bezüglich der Unterschiede zwischen domReady und $ (document) .ready ()

Beide schnüffeln im Wesentlichen auf die gleiche Weise, ob / wann das DOM bereit ist.

Aus Angst, dass jQuery zur falschen Zeit feuert

jQuery löst jeden bereitstehenden Rückruf aus, selbst wenn das DOM vor jQuery geladen wird (es sollte Ihrem Code egal sein, was zuerst passiert).

fncomp
quelle
1
Schön, das habe ich gesucht. Angemessen, gut unterstützt.
Yugal Jindle
Ich bin froh, dass ich helfen konnte :-)
fncomp
@YugalJindle Fehlt etwas für das Kopfgeld? :)
fncomp
Ich habe gerade getestet, was Sie geschrieben haben - los geht's!
Yugal Jindle
Wenn ich mir den domReady-Plugin-Code ( github.com/requirejs/domReady/blob/master/domReady.js ) ansehe, sehe ich keinen Grund, warum Sie ihn als "domReady!" Laden müssen. Anstelle von 'domReady' - können Sie mich auf den Code verweisen, der diese Verhaltensänderung verursacht?
Jez
20

Ein Versuch, Ihre Hauptfrage zu beantworten:

Warum requirejsgibt es ein domReadyPlugin, wenn wir JQuerys haben können $(document).ready();?

Sie machen wirklich zwei verschiedene Dinge. Die domReadyAbhängigkeit von RequireJS bedeutet, dass für dieses Modul das DOM vollständig geladen sein muss, bevor es ausgeführt werden kann (und daher auf Wunsch in einer beliebigen Anzahl von Modulen in Ihrer Anwendung zu finden ist)$(document).ready() stattdessen seine Rückruffunktionen ausgelöst werden, wenn sich das DOM befindet Laden beendet.

Der Unterschied mag subtil erscheinen, aber denken Sie daran: Ich habe ein Modul, das auf irgendeine Weise mit dem DOM gekoppelt werden muss, sodass ich mich entweder darauf verlassen domReadyund es zum Zeitpunkt der Moduldefinition koppeln oder $(document).ready()am Ende ein Modul ablegen kann mit einem Rückruf auf eine Init-Funktion für das Modul. Ich würde den ersten Ansatz als sauberer bezeichnen.

Wenn ich ein Ereignis habe, das genau dann eintreten muss, wenn das DOM bereit ist, ist das $(document).ready()Ereignis die richtige Adresse , da dies nicht insbesondere davon abhängt, ob RequireJS zum Laden von Modulen ausgeführt wird, vorausgesetzt, die Abhängigkeiten des Codes, den Sie verwenden Aufruf von sind erfüllt.

Beachten Sie auch, dass Sie RequireJS nicht unbedingt mit jQuery verwenden. Jedes Bibliotheksmodul, das DOM-Zugriff benötigt (aber nicht auf jQuery angewiesen ist), wäre dann weiterhin nützlich domReady.

Gert Sønderby
quelle
domReadyist keine Abhängigkeit für requirejs. Es wäre eine Abhängigkeit für den Code, wenn Sie das domReadyDocumentReady-Ereignis verwenden. Außerdem scheinen Sie verwirrend zu sein.
Yugal Jindle
1
Tolle Antwort und ein wichtiger Hinweis auf die Feinheiten, die viele Entwickler oft nicht erkennen (auch ich selbst ;-)).
Golo Roden
1
Yugal, ich habe es domReadyals Abhängigkeit bezeichnet, weil es so verwendet wird. Nicht als Abhängigkeit von RequireJS, sondern von dem Modul, in dem es verwendet wird. Vielleicht sollte ich das in meinem Text klarer machen. Haben Sie Vorschläge, wie?
Gert Sønderby
Bitte beachten Sie das Update2 zur Frage. Vielleicht sind wir nicht auf der gleichen Seite.
Yugal Jindle
Yugal, was ist, wenn Sie MooTools verwenden? Qooxdoo? Etwas nicht jQuery? RequireJS ist nicht mit jQuery verheiratet, obwohl sie zugegebenermaßen sehr gut zusammenarbeiten.
Gert Sønderby
6

Beantworten Sie Ihre Kugeln in der Reihenfolge ihres Auftretens:

  • Beide erreichen das Gleiche
  • Wenn Sie aus irgendeinem Grund Vorbehalte gegen jquery haben, verwenden Sie domReady
  • Richtig, verwenden Sie einfach jQuery
  • Weil nicht jeder jQuery verwendet
  • Ich stimme zu, benutze einfach jQuery
  • Plugins per Definition 'Feed a Need'.
  • Cross Browser Ajax ist keine Sache. Domainübergreifend? Es gibt wahrscheinlich, und wenn nicht, besteht keine Notwendigkeit zu füttern.
  • , -, -, - OK

Wenn es darauf ankommt, überdenken Sie dies. Es ist ein Mechanismus zum Ausführen von Javascript auf domReady. Wenn Sie jQuery nicht hätten, würde ich das domReady-Plugin empfehlen. Da Sie jQuery haben, laden Sie keine weiteren Skripte, um etwas zu tun, das bereits verfügbar ist.

Klarheit Update

Das domReady-Plugin sammelt Funktionen , die aufgerufen werden können, wenn das Dokument bereit ist. Wenn es bereits geladen ist, werden sie sofort ausgeführt.

JQuery sammelt Funktionen und bindet ein zurückgestelltes Objekt an den Dom, der "bereit" ist. Wenn der Dom bereit ist, wird das zurückgestellte Objekt aufgelöst und die Funktionen werden ausgelöst. Wenn der Dom bereits 'bereit' ist, wird der verzögerte bereits aufgelöst, sodass die Funktion sofort ausgeführt wird.

Dies bedeutet, dass sie effektiv genau das Gleiche tun.

Awbergs
quelle
0

Nach einigen Experimenten mit requirejs mit mehreren Modulen empfehle ich die Verwendung von domReady .

Ich habe festgestellt, dass die mit $ (document) .ready (...) verknüpfte Funktion nicht aufgerufen wird, wenn mehrere Module von requirejs geladen werden. Ich vermute, dass dom fertig wird, bevor der gesamte erforderliche Code ausgeführt wird, und der jquery ready Callback-Handler aufgerufen wird, bevor er an eine benutzerdefinierte Funktion gebunden wird, dh innerhalb des Hauptmodulcodes.

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
quelle
1
Ich bezweifle, dass, wenn Sie alle Module in Ihrer Abhängigkeitsliste haben, alle abgerufen werden und in den Speicher gelangen. poste, dass jquery dom.ready-Instanzen vor der Ausführung sammelt.
Yugal Jindle
Wenn das DOM bereits bereit ist, wird der Rückruf für $(document).readysofort ausgeführt.
Danyal Aytekin
-1

Ich habe festgestellt, dass ich dies als Teil des Haupteintrags mache, damit mein gesamtes Javascript garantiert, dass das DOM bereit ist und die Abfrage geladen wird. Ich bin mir nicht sicher, wie großartig das ist, also begrüße jedes Feedback, aber hier ist meine 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
quelle