15

He estado implementando el cargador de script yepnope como parte de la biblioteca modernizr.js. Logré que jQuery cargue correctamente y guiones dependientes de jQuery posteriormente. Soy nuevo en la carga asincrónica de recursos, por lo que es un poco nuevo para mí. He estado buscando, pero no he tenido mucha suerte con lo siguiente.

Mi pregunta es cuáles son sus opiniones sobre cómo reemplazar efectivamente la funcionalidad de $ (document) .ready() cuando se trabaja con el framework yepnope.js.

Mi teoría era crear una función apropiadamente nombrada en mi biblioteca base y luego establecer esa variable en mis páginas para una función anónima que contiene mi código $ (document) .ready() existente. Esta variable sería llamada por yepnope después de que todos los scripts se hubieran cargado en la devolución de llamada completa.

¿Está de acuerdo con que esta es una buena manera de hacerlo, o me estoy acercando a este camino completamente equivocado?

(Para aquellos que desconocen, la naturaleza asincrónica de yepnope.js significa que el documento llama $ o jQuery antes de que el cargador yepnope haya terminado, arrojando un error "$ indefinido" < - corrígeme si es incorrecto).

Primera pregunta, espero que sea una buena.

+0

podrías aclarar, estoy integrando esto en un sitio con una gran cantidad de archivos existentes js que se aplican a las páginas individuales, que dependen de document.ready(). Tal vez esta es la forma incorrecta de hacerlo, me gustaría escuchar todos sus puntos de vista. –

Respuesta

11

Si cargar jQuery sin yepnope no es un problema para ti, hay una manera más fácil de hacerlo.

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 

<script> 
    $.holdReady(true); 

    yepnope.load({ 
     load: [ 
      'placeholder.js', 
      'jquery-ui.min.js' 
     ], 
     complete: function(){ 
      $.holdReady(false); 
     } 
    }); 
</script> 
+0

¡Gracias! No tenía idea de que jQuery tuviera esta característica. Solución mucho más simple y más elegante. –

+0

puse $ (document) .ready(); justo debajo de esto? ¿necesita estar en su etiqueta '

1

etiquetas script se cargan de forma sincrónica - por lo que si usted pone su yepnope en un archivo js y lo cargan a través de etiquetas de script:

<script type="text/javascript" src="/my-yepnope-stuff.js"></script> 
</body> 

justo antes de la etiqueta del cuerpo de cierre puede estar completamente seguro de estar en $ (document) .ready() estado.

Lo que debe responder por sí mismo es si tiene sentido obligar a yepnope a cargar en un modo $ (document) .ready(), ya que su objetivo principal es romper el orden de carga síncrono de las etiquetas de secuencia de comandos en el primer lugar.

+0

Mi problema es que, en algunos casos, debo probar si el documento está listo, ya que utilizo bibliotecas de control de terceros (telerik). Sus funciones devuelven nulos si no se pueden encontrar los controles (es decir, que aún no están cargados). Aparte de esto, me gustaría trabajar para tener una carga de script asíncrona. –

0

Usando la guía de @ezmilhouse, pensé en la mejor manera de lograr lo que buscaba manteniendo la compatibilidad con nuestro código anterior.

Mi solución fue configurar mi script yepnope para cargar todos los scripts necesarios de forma jerárquica, en función de sus dependencias individuales. Una vez que se carguen todas las secuencias de comandos, puede usar la propiedad complete de mi llamada a yepnope para llamar a mi función lista. Esto significaba que el documento estaba efectivamente listo y el código funcionaría sin problemas.

También se ha llevado mi js a la base de mis páginas (algo que debería haber hecho hace mucho tiempo, pero que tenía una gran cantidad de páginas de legado! :))

Aquí es un ejemplo (con datos falsos nombres libray/script sólo para fines ilustrativos):

yepnope({ 
    test: baseLib.debug, 
    yep: { "max": "/version2/res/jquery/jquery-1.5.2.js" }, 
    nope: { "min": "/version2/res/jquery/jquery-1.5.2.min.js" }, 
    callback: { 
     "max": function (url, result, key) { 
      baseLib.Log("jQuery full loaded."); 
     }, 
     "min": function (url, result, key) { 
      baseLib.Log("jQuery min loaded."); 
     } 
    }, 
    complete: function() { 
     if (window.$) { 
      yepnope({ 
       test: base.debug, 
       yep: { 
        "anotherscript": "script/url/here.js", 
        "anotherscript2": "script/url/here2.js" 
       }, 
       nope: { 
        "anotherscript": "script/url/here-min.js", 
        "anotherscript2": "script/url/here2-min.js" 
       }, 
       both: { 
        "anotherscript3": "script/url/here3.js" 
       }, 
       callback: { 
        "anotherscript": function (url, result, key) { 
         baseLib.Log("anotherscript " + (result ? "Max" : "Min") + " loaded."); 

        }, 
        "anotherscript2": function (url, result, key) { 
         baseLib.Log("anotherscript2 " + (result ? "Max" : "Min") + " loaded."); 
        }, 
        "anotherscript3": function (url, result, key) { 
         baseLib.Log("anotherscript3 loaded."); 
        } 
       }, 
       complete: function() { 
        baseLib.Log("Scripts Loaded"); 
        baseLib.Page.Ready(); 
       } 
      }); 

     } 
     else { 
      baseLib.Log("Could not load jQuery. No further jQuery dependent files loaded.", "error"); 
     } 
    } 
}); 

en mi página js voy a asignar una función a baseLib.Page.Ready que luego serán llamados por el yepnope completa.

11

Esta es la técnica que uso. Me permite rociar llamadas de estilo $ (document) .ready() donde me gusta. Con este método, puede tomar un sitio que ya usa jQuery y tiene llamadas existentes $ (document) .ready(), y puede actualizar fácilmente yepnope.

Primero, agregue esta línea de JS, preferiblemente en el encabezado del documento, antes de cualquier javascript que llame a $ (documento).ready():

<script> 
    var docready=[],$=function(o){function r(fn){docready.push(fn);}if(typeof o === 'function') r(o);return{ready: r}}; 
</script> 

Luego, haga que su yepnope jQuery objeto de prueba ajustado similar a esto:

yepnope({ 
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js', 
    complete: function() { 
     $ = jQuery;   
     for(n in docready) $(document).ready(docready[n]); 
    } 
}); 

creamos una falsa ready $ (document)() antes de cargar jQuery. Esto almacena cada llamada a $ (document) .ready() en una matriz, docready. Luego, una vez que jQuery se haya cargado, sobrescribimos nuestro objeto $ temporal con el objeto jQuery real cargado. Luego, iteramos a través de todas las llamadas $ (document) .ready() almacenadas y las ejecutamos de manera real.

ACTUALIZADO: versión mejorada de Chris Jones que también cubre las invocaciones de estilo $ (function() {}).

+0

Hola, utilicé el método que describes y coloqué el yepnope justo antes de la etiqueta de cierre del cuerpo, todo funciona bien. Pero: cargué el jquery.min.js en algún lugar antes, ¿así que usar este método cargará un jquery innecesario de nuevo? Recuerdos Andrea – cwhisperer

+0

Hola Andrea: si ya has intentado cargar jQuery de antemano, puedes 1) eliminar la llamada de yepnope que carga jquery y dejar tus otros scripts, 2) cambiar el bloque yepnope que carga jQuery a esto: { prueba: typeof jQuery == 'indefinido', sip: '' //ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js, completa: function() {$ = jQuery; para (n en docready) $ (documento) .ready (docready [n]); } } 3) elimine su carga síncrona anterior de jQuery y ajuste cualquier llamada que use jQuery en bloques $ (documento) .ready (función() {...}). – Sc0ttyD

+1

Buena solución. Definitivamente voy a intentarlo también. Pero, ¿cómo manejar los plugins JQuery que están registrados a través de JQuery.fn o $ .fn en este escenario? Creo que esto último es lo peor, porque esos registros tendrán éxito y se sobrescribirán después;) ... ¿O me falta algún punto aquí sobre los complementos que hacen que sigan funcionando como se esperaba? – DotBert

0

creo que Alex Sexton solution sería correcto:

yepnope({ 
    load: '//ajax.googleapisOFFLINE.com/ajaxX/libs/jquery/1.7.1/jquery.min.js', 
    callback: function() { 
     if (!window.jQuery) { 
      yepnope('/js/jquery-1.7.1.min.js'); 
     } 
    }, 
    complete: function() { 
     $(function(){ 
     $("div.whatever").css("color","red"); 
     }); 
    } 
}); 
Cuestiones relacionadas