Requirejs plug-in domReady vs Jquery $ (document) .ready ()?


100

Sto usando RequireJS e ho bisogno di inizializzare qualcosa su DOM pronto. Ora, RequireJS fornisce il domReadyplug-in , ma abbiamo già jQuery $(document).ready(), che è disponibile per me poiché ho richiesto jQuery.

Quindi ho due opzioni:

  1. Usa il domReadyplugin:

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

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

Quale dovrei scegliere e perché?

Entrambe le opzioni sembrano funzionare come previsto. Non sono fiducioso in quello di jQuery perché RequireJS sta facendo la sua magia; cioè, poiché RequireJS aggiungerà dinamicamente gli script, sono preoccupato che il DOM ready possa verificarsi prima che tutti gli script richiesti dinamicamente vengano caricati. Considerando che, RequireJS aggiungerà un peso su JS aggiuntivo solo per domReadyquando ho già richiesto jQuery.

Domande

  • Perché RequireJS fornisce un domReadyplugin quando possiamo avere jQuery $(document).ready();? Non vedo alcun vantaggio nell'includere un'altra dipendenza.
  • Se è solo per soddisfare un bisogno, perché non fornirne uno per AJAX cross-browser?

Per quanto ne so, un modulo che richiede domReadynon verrà recuperato o eseguito dopo che il documento è pronto, e potresti fare lo stesso anche richiedendo jQuery:

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

Per essere più chiari sulla mia domanda: qual è la differenza tra richiedere domReadyo jQuery?


4
I am not confident in jquery's dom readyVoglio contrassegnarlo come offensivo:p
Dakait

3
Il dom ready di jQuery è perfettamente affidabile, anche su IE. Milioni di persone lo usano ogni giorno senza saperlo ;-)
John Dvorak

1
Hai il controllo di dove scriptvanno i tuoi tag o stai scrivendo una libreria / plug-in che altre persone useranno (e quindi hanno il controllo della posizione dei scripttag nel markup)?
TJ Crowder

3
Oddio .. leggilo con il contesto completo. I am not confident in jquery's dom ready because requirejs is doing its magic.Poiché, require incapsula jquery in un ambito locale limitato. Non è questo il punto. (per quanto riguarda la domanda).
Yugal Jindle

1
Grazie, @TJCrowder per la modifica.
Yugal Jindle

Risposte:


91

Sembra che tutti i punti chiave siano già stati raggiunti, ma alcuni dettagli sono caduti nel dimenticatoio. Principalmente:

domReady

È sia un plugin che un modulo. Se lo includi nell'array dei requisiti con un finale, il !tuo modulo non verrà eseguito finché non sarà "sicuro" interagire con il DOM:

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

Notare che il caricamento e l'esecuzione sono diversi; vuoi che tutti i tuoi file vengano caricati il ​​prima possibile, è l'esecuzione dei contenuti che dipende dal tempo.

Se ometti il !, allora è solo un normale modulo che sembra essere una funzione, che può richiedere un callback che non verrà eseguito prima che il DOM sia sicuro con cui interagire:

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

Vantaggio quando si utilizza domReady come plugin

Il codice che dipende da un modulo da cui dipende a sua volta domReady!ha un vantaggio molto significativo: non è necessario attendere che il DOM sia pronto!

Diciamo che abbiamo un blocco di codice, A, che dipende da un modulo, B, da cui dipende domReady!. Il modulo B non terminerà il caricamento prima che il DOM sia pronto. A sua volta, A non verrà eseguito prima che B sia stato caricato.

Se dovessi usarlo domReadycome un normale modulo in B, sarebbe anche necessario che A dipendesse domReady, oltre a racchiudere il suo codice all'interno di una domReady()chiamata di funzione.

Inoltre, questo significa che domReady!gode dello stesso vantaggio rispetto a $(document).ready().

Re le differenze tra domReady e $ (document) .ready ()

Entrambi scoprono se / quando il DOM è pronto essenzialmente nello stesso modo.

Temo che jQuery si attivi nel momento sbagliato

jQuery attiverà qualsiasi callback pronto anche se il DOM viene caricato prima di jQuery (il tuo codice non dovrebbe preoccuparsi di cosa accade per primo).


1
Bello, questo è quello che stavo cercando. Ragionevole, ben supportato.
Yugal Jindle

Sono contento di aver potuto aiutare :-)
fncomp

@YugalJindle Manca qualcosa per la taglia? :)
fncomp

Stavo solo provando quello che hai scritto - ecco qua!
Yugal Jindle

Guardando il codice del plugin domReady ( github.com/requirejs/domReady/blob/master/domReady.js ) non vedo alcun motivo per cui devi caricarlo come "domReady!" invece di "domReady", potresti indicarmi il bit di codice che causa quel cambiamento nel comportamento?
Jez

20

Un tentativo di rispondere alla tua domanda principale:

Perché requirejsfornisce un domReadyplugin quando possiamo avere jquery $(document).ready();?

Fanno due cose diverse, davvero. La domReadydipendenza di RequireJS significa che questo modulo richiede che il DOM sia completamente caricato prima di poter essere eseguito (e può quindi essere trovato in un numero qualsiasi di moduli nella tua applicazione se lo desideri), mentre $(document).ready()invece attiva le sue funzioni di callback quando il DOM è caricamento fatto.

La differenza può sembrare sottile, ma pensa a questo: ho un modulo che deve essere accoppiato in qualche modo al DOM, quindi posso dipendere da domReadye accoppiarlo al momento della definizione del modulo, o mettere un $(document).ready()alla fine di esso con una richiamata a una funzione di inizializzazione per il modulo. Chiamerei il primo approccio più pulito.

Nel frattempo, se ho un evento che deve accadere proprio mentre il DOM è pronto, l' $(document).ready()evento sarebbe il punto di partenza, poiché ciò non dipende in particolare dal caricamento dei moduli di RequireJS, a condizione che le dipendenze del codice che stai chiamandolo da sono soddisfatte.

Vale anche la pena considerare che non usi necessariamente RequireJS con jQuery. Qualsiasi modulo libreria che necessita dell'accesso DOM (ma non si basa su jQuery) sarebbe comunque utile utilizzando domReady.


domReadynon è una dipendenza per requirejs. Sarebbe una dipendenza per il codice se si utilizza domReadyper l'evento DocumentReady. Inoltre sembri confondere.
Yugal Jindle

1
Ottima risposta e un suggerimento importante per le sottigliezze che molti sviluppatori spesso non realizzano (me compreso ;-)).
Golo Roden

1
Yugal, mi riferivo a domReadyuna dipendenza, perché è così che viene utilizzata. Non come dipendenza di RequireJS, ma del modulo in cui viene utilizzato. Forse dovrei renderlo più chiaro nel mio testo, hai suggerimenti su come?
Gert Sønderby

Si prega di consultare Update2 sulla domanda. Forse non siamo sulla stessa pagina.
Yugal Jindle

Yugal, cosa succede se usi MooTools? Qooxdoo? Qualcosa che non sia jQuery? RequireJS non è sposato con jQuery, sebbene funzionino davvero bene insieme.
Gert Sønderby

6

Rispondere ai tuoi proiettili in ordine di apparizione:

  • Entrambi realizzano la stessa cosa
  • Se hai delle riserve su jquery per qualsiasi motivo, usa domReady
  • Corretto, quindi usa jQuery
  • Perché non tutti usano jQuery
  • Sono d'accordo, usa solo jQuery
  • I plugin per definizione "alimentano un bisogno".
  • Cross Browser ajax non è una cosa. Cross Domain? Probabilmente c'è, e se non c'è, non c'è bisogno di nutrirsi.
  • , -, -, - Ok

Quando arriva il momento, stai pensando troppo a questo. È un meccanismo per eseguire javascript su domReady. Se non avessi jQuery, ti consiglio il plugin domReady. Dato che hai jQuery, non caricare più script per fare qualcosa che è già disponibile.

Aggiornamento chiarezza

Il plugin domReady raccoglie le funzioni da chiamare quando il documento è "pronto". Se è già caricato, vengono eseguiti immediatamente.

JQuery raccoglie le funzioni e associa un oggetto differito al dominio che è "pronto". Quando il dom è pronto l'oggetto posticipato sarà risolto e le funzioni si attiveranno. Se il dom è già "pronto", il differito sarà già risolto, quindi la funzione verrà eseguita immediatamente.

Ciò significa che effettivamente fanno esattamente la stessa cosa.


0

Dopo alcuni esperimenti con requirejs con più moduli, suggerisco di usare domReady .

Ho notato che la funzione associata a $ (document) .ready (...) non viene chiamata quando più moduli vengono caricati da requirejs. Sospetto che dom si stia preparando prima che tutto il codice requirejs venga eseguito e che il gestore di callback pronto per jquery venga chiamato prima che venga associato alla funzione definita dall'utente, cioè all'interno del codice del modulo principale.

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

1
Ne dubito, se hai tutti i moduli nella tua lista delle dipendenze, allora tutti verranno recuperati e entreranno in memoria. post che jquery raccoglie le istanze di dom.ready prima dell'esecuzione.
Yugal Jindle

Se il DOM è già pronto, la richiamata per $(document).readyverrà eseguita immediatamente.
Danyal Aytekin

-1

Ho scoperto di farlo come parte della voce principale in modo che tutto il mio javascript sia garantito che il DOM sia pronto e che jquery sia caricato. Non sono sicuro di quanto sia bello questo, quindi benvenuto qualsiasi feedback, ma ecco il mio 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');
        });
    });
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.