¿Requirejs domReady plugin vs Jquery $ (documento) .ready ()?

100

Estoy usando RequireJS y necesito inicializar algo en DOM listo. Ahora, RequireJS proporciona el domReadycomplemento , pero ya tenemos jQuery $(document).ready(), que está disponible para mí ya que he requerido jQuery.

Entonces tengo dos opciones:

  1. Utilice el domReadycomplemento:

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

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

¿Cuál debería elegir y por qué?

Ambas opciones parecen funcionar como se esperaba. No confío en el de jQuery porque RequireJS está haciendo su magia; es decir, dado que RequireJS agregará scripts dinámicamente, me preocupa que DOM ready pueda ocurrir antes de que se carguen todos los scripts solicitados dinámicamente. Considerando que, RequireJS agregará una carga en JS adicional solo para domReadycuando ya tenga jQuery requerido.

Preguntas

  • ¿Por qué RequireJS proporciona un domReadycomplemento cuando podemos tener jQuery $(document).ready();? No veo ninguna ventaja en incluir otra dependencia.
  • Si es solo para satisfacer una necesidad, ¿por qué no proporcionar uno para AJAX entre navegadores?

Hasta donde yo sé, un módulo que requiera domReadyno se obtendrá ni se ejecutará después de que el documento esté listo, y usted podría hacer lo mismo requiriendo jQuery también:

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

Para ser más claro en mi pregunta: ¿cuál es la diferencia entre requerir domReadyo jQuery?

Yugal Jindle
fuente
4
I am not confident in jquery's dom readyQuiero marcarlo como ofensivo:p
Dakait
3
dom ready de jQuery es perfectamente confiable, incluso en IE. Millones de personas lo usan todos los días sin saberlo ;-)
John Dvorak
1
¿Tiene el control de dónde scriptvan sus etiquetas o está escribiendo una biblioteca / complemento que otras personas usarán (y así ellos tienen el control de la ubicación de las scriptetiquetas en el marcado)?
TJ Crowder
3
Oh dios ... léelo con el contexto completo. I am not confident in jquery's dom ready because requirejs is doing its magic.Dado que, require encapsula jquery en un ámbito local limitado. Ese no es el punto. (en lo que respecta a la pregunta).
Yugal Jindle
1
Gracias, @TJCrowder por la edición.
Yugal Jindle

Respuestas:

91

Parece que todos los puntos clave ya fueron alcanzados, pero algunos detalles pasaron desapercibidos. Principalmente:

domReady

Es tanto un complemento como un módulo. Si lo incluye en la matriz de requisitos con un seguimiento, !su módulo no se ejecutará hasta que sea "seguro" interactuar con el DOM:

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

Tenga en cuenta que cargar y ejecutar son diferentes; desea que todos sus archivos se carguen lo antes posible, es la ejecución de los contenidos lo que es sensible al tiempo.

Si omite !, entonces es solo un módulo normal que resulta ser una función, que puede recibir una devolución de llamada que no se ejecutará antes de que el DOM sea seguro para interactuar:

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

Ventaja al usar domReady como complemento

El código que depende de un módulo que a su vez depende domReady!tiene una ventaja muy significativa: ¡no necesita esperar a que el DOM esté listo!

Digamos que tenemos un bloque de código, A, que depende de un módulo, B, que depende de domReady!. El módulo B no terminará de cargarse antes de que DOM esté listo. A su vez, A no se ejecutará antes de que B se haya cargado.

Si lo usara domReadycomo un módulo regular en B, también sería necesario que A dependiera de él, además de incluir domReadysu código dentro de una domReady()llamada de función.

Además, esto significa que domReady!disfruta de esa misma ventaja sobre $(document).ready().

Ver las diferencias entre domReady y $ (document) .ready ()

Ambos analizan si / cuándo el DOM está listo esencialmente de la misma manera.

Por miedo a que jQuery se dispare en el momento equivocado

jQuery activará cualquier devolución de llamada lista incluso si el DOM se carga antes de que lo haga jQuery (a su código no le debería importar qué sucede primero).

fncomp
fuente
1
Hermoso, esto es lo que estaba buscando. Razonable, bien respaldado.
Yugal Jindle
Me alegro de haber podido ayudar :-)
fncomp
@YugalJindle ¿Falta algo para la recompensa? :)
fncomp
Solo estaba probando lo que escribiste, ¡aquí tienes!
Yugal Jindle
Mirando el código del complemento domReady ( github.com/requirejs/domReady/blob/master/domReady.js ) no veo ninguna razón por la que necesite cargarlo como 'domReady!' en lugar de 'domReady', ¿podría indicarme el fragmento de código que causa ese cambio en el comportamiento?
Jez
20

Un intento de responder a su pregunta principal:

¿Por qué requirejsproporciona un domReadycomplemento cuando podemos tener jquery $(document).ready();?

Realmente hacen dos cosas diferentes. La domReadydependencia de RequireJS significa que este módulo requiere que el DOM se cargue por completo antes de que pueda ejecutarse (y por lo tanto se puede encontrar en cualquier número de módulos en su aplicación si así lo desea), mientras que $(document).ready()en su lugar activa sus funciones de devolución de llamada cuando el DOM está terminado de cargar.

La diferencia puede parecer sutil, pero piense en esto: tengo un módulo que debe acoplarse al DOM de alguna manera, por lo que puedo depender domReadyy acoplarlo en el momento de la definición del módulo, o poner un $(document).ready()al final con una devolución de llamada a una función init para el módulo. Yo llamaría limpiador al primer acercamiento.

Mientras tanto, si tengo un evento que debe suceder justo cuando el DOM está listo, el $(document).ready()evento sería el ideal, ya que eso no depende en particular de que RequireJS esté cargando módulos, siempre que las dependencias del código que está llamándolo desde se cumplen.

También vale la pena considerar que no necesariamente usa RequireJS con jQuery. Cualquier módulo de biblioteca que necesite acceso DOM (pero que no dependa de jQuery) sería útil usando domReady.

Gert Sønderby
fuente
domReadyno es una dependencia para requirejs. Sería una dependencia para el código si está utilizando domReadypara el evento DocumentReady. Además, parece confuso.
Yugal Jindle
1
Gran respuesta, y una pista importante para las sutilezas que muchos desarrolladores a menudo no se dan cuenta (incluyéndome a mí ;-)).
Golo Roden
1
Yugal, me refería a domReadyuna dependencia, porque así es como se usa. No como una dependencia de RequireJS, sino del módulo donde se usa. Quizás debería dejar eso más claro en mi texto, ¿tiene alguna sugerencia sobre cómo?
Gert Sønderby
Consulte Update2 sobre la pregunta. Puede ser que no estemos en la misma página.
Yugal Jindle
Yugal, ¿y si usas MooTools? Qooxdoo? ¿Algo que no sea jQuery? RequireJS no está casado con jQuery, aunque es cierto que funcionan muy bien juntos.
Gert Sønderby
6

Respondiendo a sus balas en orden de aparición:

  • Ambos logran lo mismo
  • Si tiene reservas sobre jquery por cualquier motivo, utilice domReady
  • Correcto, solo usa jQuery
  • Porque no todo el mundo usa jQuery
  • Estoy de acuerdo, solo usa jQuery
  • Los complementos, por definición, "alimentan una necesidad".
  • Cross Browser ajax no es una cosa. ¿Dominio cruzado? Probablemente la haya, y si no la hay, no hay necesidad de alimentarse.
  • , -, -, - Okay

Cuando se trata de eso, estás pensando demasiado en esto. Es un mecanismo para ejecutar javascript en domReady. Si no tuviera jQuery, recomendaría el complemento domReady. Como tiene jQuery, no cargue más scripts para hacer algo que ya está disponible.

Actualización de claridad

El complemento domReady recopila funciones para llamar cuando el documento está "listo". Si ya está cargado, se ejecutan inmediatamente.

JQuery recopila funciones y vincula un objeto diferido al dom que está 'listo'. Cuando el dom esté listo, el objeto diferido se resolverá y las funciones se dispararán. Si el dom ya está 'listo', el aplazado ya se resolverá, por lo que la función se ejecutará de inmediato.

Esto significa que efectivamente hacen exactamente lo mismo.

awbergs
fuente
0

Después de experimentar un poco con requirejs con varios módulos, sugiero usar domReady .

Noté que la función asociada con $ (document) .ready (...) no se llama cuando requirejs carga varios módulos. Sospecho que dom se está preparando antes de que se ejecute todo el código requirejs y se llame al controlador de devolución de llamada listo para jquery antes de que se vincule con la función definida por el usuario, es decir, dentro del código del módulo 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
fuente
1
Dudo que, si tiene todos los módulos en su lista de dependencias, entonces todos serán recuperados y entrarán en la memoria. post que jquery recopila instancias dom.ready antes de la ejecución.
Yugal Jindle
Si el DOM ya está listo, la devolución de llamada $(document).readyse ejecutará inmediatamente.
Danyal Aytekin
-1

Descubrí que hago esto como parte de la entrada principal para que todo mi javascript esté garantizado de que el DOM está listo y jquery está cargado. No estoy seguro de lo bueno que es esto, así que agradezco cualquier comentario, pero aquí está mi 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
fuente