2010-06-13 30 views
14

Estoy tratando de escribir una solución ultra simple para cargar un grupo de archivos JS de forma asincrónica. Tengo el siguiente script a continuación hasta ahora. Sin embargo, a veces se llama a la devolución de llamada cuando los scripts no se cargan realmente, lo que causa un error de variable no encontrada. Si actualizo la página a veces, simplemente funciona porque supongo que los archivos vienen directamente de la caché y, por lo tanto, están allí más rápido de lo que se llama, ¿es muy extraño?Async Cargar archivos de JavaScript con devolución de llamada

var Loader = function() { 

} 
Loader.prototype = { 
    require: function (scripts, callback) { 
     this.loadCount  = 0; 
     this.totalRequired = scripts.length; 
     this.callback  = callback; 

     for (var i = 0; i < scripts.length; i++) { 
      this.writeScript(scripts[i]); 
     } 
    }, 
    loaded: function (evt) { 
     this.loadCount++; 

     if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call(); 
    }, 
    writeScript: function (src) { 
     var self = this; 
     var s = document.createElement('script'); 
     s.type = "text/javascript"; 
     s.async = true; 
     s.src = src; 
     s.addEventListener('load', function (e) { self.loaded(e); }, false); 
     var head = document.getElementsByTagName('head')[0]; 
     head.appendChild(s); 
    } 
} 

¿Hay alguna forma de probar que un archivo JS está completamente cargado, sin poner algo en el archivo JS en sí, porque me gustaría usar el mismo patrón para cargar bibliotecas fuera de mi control (GMaps etc) .

Invocando el código, justo antes de la etiqueta.

var l = new Loader(); 
l.require([ 
    "ext2.js", 
    "ext1.js"], 
    function() { 
     var config = new MSW.Config(); 
     Refraction.Application().run(MSW.ViewMapper, config); 
     console.log('All Scripts Loaded'); 
    }); 

Gracias por cualquier ayuda.

+0

En qué navegador y versión está probando este? –

+0

En el último WebKit, también lo hace en la última versión de desarrollo de Chrome :( – Gcoop

+0

No puedo reproducir esto usando Chromium 5.0.375.70, cargando dos scripts de un CDN y uno de localhost (que contiene una función necesaria para ejecutar un línea dentro de la función de devolución de llamada). Pero, ¿es realmente necesario el indicador 'async'? ¿Qué sucede si comenta' s.async = true; 'out? –

Respuesta

2

No hay nada malo con su código de lo que puedo decir, este es sólo un error en Chrome (lo hace con window.onload también.)

que me gustaría añadir a la función que se activa en la función "cargar". Si la variable existe, ejecute el código JS, pero si no lo hace, use un setTimeout para verificar nuevamente en 500ms o menos.

+0

También puede probar una función presente: por ejemplo, si desea cargar jQuery de esta manera, puede probar que la función '$' esté presente en el alcance global: 'if ('$' en la ventana)/* hacer algo * /;' –

+0

Gracias también agregó este cheque :) – Gcoop

2

Sólo en caso de que encuentre útil, he creado una biblioteca de utilidades asíncrono que permite escribir el código anterior como:

var Loader = function() {} 

Loader.prototype = { 
    require: function (scripts, callback) { 
     async.map(scripts, this.writeScript, callback); 
    }, 
    writeScript: function(src, callback) { 
     var s = document.createElement('script'); 
     s.type = "text/javascript"; 
     s.src = src; 
     s.addEventListener('load', function (e) { callback(null, e); }, false); 
     var head = document.getElementsByTagName('head')[0]; 
     head.appendChild(s); 
    } 
} 

si está haciendo un montón de llamadas asíncronas se ha algunas bastante potentes funciones :)

http://caolanmcmahon.com/async.html

4

¿Qué pasa con jQuery ....

$.getScript('abc.js'); 

El código anterior cargará el archivo de script "abc.js" de forma asíncrona ....

+2

Estoy usando el xui framework ya y no desea incluir el framework jQuery, solo agregará un peso extra :) Aunque no sabía que jQuery podría hacer esto, ¡gracias! – Gcoop

+0

'getScript' no tiene una devolución de llamada que se invoca una vez que se ha ejecutado el script. – Flimm

0

Como Aaron dice que hay un error en Chrome, pero también hay problemas en IE y otros navegadores.

He probado diferentes maneras de crear mi cargador de perezosos y que tenía un montón de problemas:

  • la adición de un > etiqueta < guión: problemas con los eventos de script (. Onload, onerror, etc) en el explorador y otra navegadores
  • leyendo un script con ajax y analizando el texto (con eval, es javascript, así que no se preocupe, no es evidente): MUY difícil de depurar (se analiza como una sola línea sin comentarios, por lo que no puede saber qué línea le da un error)
  • leyendo el guión con ajax y agregando un <script> etiqueta con el texto del script: funciona muy bien en todos los navegadores; puede crear una carga sincronizada y sincronizada con la misma función y también puede controlar errores muy bien, cargar etc. (si conoce los conceptos básicos de ajax, debe saber cómo manejar el estado http variado) y es lo que recomiendo.
3

le recomiendo que utilice un pequeño cargador de Javascript como JcorsLoader (sólo 647B con gzip)

JcorsLoader.load(
       "http://xxxx/jquery.min.js", 
       function() { 
        $("#demo").html("jQuery Loaded"); 
       }, 
       "http://xxxx/jquery.cookie.js", 
       function() { 
        $.cookie('not_existing'); 
       } 
      ); 

carga múltiplos js en paralelo y ejecutar con el fin domready sin bloquear o proceso de carga.

https://github.com/pablomoretti/jcors-loader

0

jcors-loader.js no funciona en Internet Explorer ...

Index.HTML

<html> 
    <head> 
    <script type="text/javascript" src="/js/jcors-loader.js"></script> 
    <script> 
     JcorsLoader.load(
       "js/jquery-1.8.0.js", 
       "/js/alertme.js", 
       function() { 
        $("#result").text("TEST OK"); 
       } 
     ); 

    </script> 
    </head> 
    <body> 
    <h1 id="result"></h1> 
    </body> 
    </html> 

alertme.js alerta

(" Cargado");

Esto funciona bien en Chrome y Firefox muestra "PRUEBA OK" y ventana emergente ... Pero no hay mensaje o alerta en IE (7,8,9) ... Cualquier ayuda será apreciada.

-1

Aku menggabungkan scrpit callback dengan información sobre herramientas, didalam template blogger. kemudian didalamnya guión ditambahkan callbak menggunakan javascipt

Script callback with tooltip

<style> 
 
/* Tooltip container */ 
 
.tooltip { 
 
    position: relative; 
 
    display: inline-block; 
 
    text-transform: italic; 
 
    color: blue; 
 
    border-bottom: 1px dotted black; 
 
} 
 

 

 
.tooltip .tooltiptext { 
 
    visibility: hidden; 
 
    width: 400px; 
 
    background-color: #fff; 
 
    border: 2px solid #cc6611; 
 
    color: black; 
 
    text-align: left; 
 
\t top: 0; left: 6px; 
 
    border-radius: 6px; 
 
\t box-shadow: 0 2px 4px -2px #716e6c; 
 
    padding: 15px; 
 
    position: absolute; 
 
    z-index: 999; 
 
    top: 90%; 
 
    left: 10%; 
 
    margin-left: -10px; 
 
} 
 

 
.tooltip .tooltiptext::after { 
 
    content: ""; 
 
    position: absolute; 
 
    bottom: 100%; 
 
    left: 10%; 
 
    margin-left: -10px; 
 
    border-width: 10px; 
 
    border-style: solid; 
 
    border-color: transparent transparent #cc6611 transparent; 
 
} 
 

 
.tooltip:hover .tooltiptext { 
 
    visibility: visible; 
 
} 
 
</style> 
 

 
<span class='tooltip'><span class='tooltiptext'><script> 
 
document.write("<script src=\"/feeds/posts/default/-/Your Label Post?max-results="+numposts4+"&orderby=published&alt=json-in-script&callback=showrecentposts4\"><\/script>"); 
 
</script> 
 
</span></span>
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
<script type='text/javascript'> 
 
//<![CDATA[ 
 

 
imgr = new Array(); 
 
imgr[0] = "http://2.bp.blogspot.com/-uitX7ROPtTU/Tyv-G4NA_uI/AAAAAAAAFBY/NcWLPVnYEnU/s1600/no+image.jpg"; 
 
showRandomImg = true; 
 
aBold = true; 
 
summaryPost = 170; 
 
summaryPost4 = 160; 
 
summaryTitle = 100; 
 
numposts = 10; 
 
numposts4 = 5; 
 

 
function removeHtmlTag(strx,chop){ 
 
    var s = strx.split("<"); 
 
    for(var i=0;i<s.length;i++){ 
 
     if(s[i].indexOf(">")!=-1){ 
 
      s[i] = s[i].substring(s[i].indexOf(">")+1,s[i].length); 
 
     } 
 
    } 
 
    s = s.join(""); 
 
    s = s.substring(0,chop-1); 
 
    return s; 
 
} 
 

 
function showrecentposts(json) { 
 
    j = (showRandomImg) ? Math.floor((imgr.length+1)*Math.random()) : 0; 
 
    img = new Array(); 
 

 
     for (var i = 0; i < numposts; i++) { 
 
     var entry = json.feed.entry[i]; 
 
     var posttitle = entry.title.$t; 
 
     var pcm; 
 
     var posturl; 
 
     if (i == json.feed.entry.length) break; 
 
     for (var k = 0; k < entry.link.length; k++) { 
 
       if (entry.link[k].rel == 'alternate') { 
 
       posturl = entry.link[k].href; 
 
       break; 
 
       } 
 
     } 
 
     
 
     for (var k = 0; k < entry.link.length; k++) { 
 
       if (entry.link[k].rel == 'replies' && entry.link[k].type == 'text/html') { 
 
       pcm = entry.link[k].title.split(" ")[0]; 
 
       break; 
 
       } 
 
     } 
 
     
 
     if ("content" in entry) { 
 
       var postcontent = entry.content.$t;} 
 
     else 
 
     if ("summary" in entry) { 
 
       var postcontent = entry.summary.$t;} 
 
     else var postcontent = ""; 
 
     
 
     postdate = entry.published.$t; 
 
    
 
    if(j>imgr.length-1) j=0; 
 
    img[i] = imgr[j]; 
 
    
 
    s = postcontent ; a = s.indexOf("<img"); b = s.indexOf("src=\"",a); c = s.indexOf("\"",b+5); d = s.substr(b+5,c-b-5); 
 

 
    if((a!=-1)&&(b!=-1)&&(c!=-1)&&(d!="")) img[i] = d; 
 

 
    //cmtext = (text != 'no') ? '<i><font color="'+acolor+'">('+pcm+' '+text+')</font></i>' : ''; 
 

 

 
    var month = [1,2,3,4,5,6,7,8,9,10,11,12]; 
 
    var month2 = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; 
 

 
    var day = postdate.split("-")[2].substring(0,2); 
 
    var m = postdate.split("-")[1]; 
 
    var y = postdate.split("-")[0]; 
 

 
    for(var u2=0;u2<month.length;u2++){ 
 
     if(parseInt(m)==month[u2]) { 
 
      m = month2[u2] ; break; 
 
     } 
 
    } 
 

 
    var daystr = day+ ' ' + m + ' ' + y ; 
 
    
 
    var trtd = '<li style="position:relative;"><div class="imgauto"><a href="'+posturl+'"><img width="200" height="150" class=" " src="'+img[i]+'"/></a></div><h3><a href="'+posturl+'">'+posttitle+'</a><p>'+daystr+'/'+pcm+' comments</p></h3></li>';      
 
     document.write(trtd); 
 
       
 
       j++; 
 
    } 
 
    
 
} 
 

 
function showrecentposts4(json) { 
 
\t j = (showRandomImg) ? Math.floor((imgr.length+1)*Math.random()) : 0; 
 
\t img = new Array(); 
 
    if (numposts4 <= json.feed.entry.length) { 
 
\t \t maxpost = numposts4; 
 
\t \t } 
 
\t else 
 
     { 
 
\t maxpost=json.feed.entry.length; 
 
\t } \t 
 
    \t for (var i = 0; i < maxpost; i++) { 
 
    \t var entry = json.feed.entry[i]; 
 
    \t var posttitle = entry.title.$t; 
 
\t \t var pcm; 
 
    \t var posturl; 
 
    \t if (i == json.feed.entry.length) break; 
 
    \t for (var k = 0; k < entry.link.length; k++) { 
 
     \t \t if (entry.link[k].rel == 'alternate') { 
 
     \t \t posturl = entry.link[k].href; 
 
     \t \t break; 
 
     \t \t } 
 
    \t } 
 
\t \t 
 
\t \t for (var k = 0; k < entry.link.length; k++) { 
 
     \t \t if (entry.link[k].rel == 'replies' && entry.link[k].type == 'text/html') { 
 
     \t \t pcm = entry.link[k].title.split(" ")[0]; 
 
     \t \t break; 
 
     \t \t } 
 
    \t } 
 
\t \t 
 
    \t if ("content" in entry) { 
 
     \t \t var postcontent = entry.content.$t;} 
 
    \t else 
 
    \t if ("summary" in entry) { 
 
     \t \t var postcontent = entry.summary.$t;} 
 
    \t else var postcontent = ""; 
 
    \t 
 
    \t postdate = entry.published.$t; 
 
\t 
 
\t if(j>imgr.length-1) j=0; 
 
\t img[i] = imgr[j]; 
 
\t 
 
\t s = postcontent \t ; a = s.indexOf("<img"); b = s.indexOf("src=\"",a); c = s.indexOf("\"",b+5); d = s.substr(b+5,c-b-5); 
 

 
\t if((a!=-1)&&(b!=-1)&&(c!=-1)&&(d!="")) img[i] = d; 
 

 
\t //cmtext = (text != 'no') ? '<i><font color="'+acolor+'">('+pcm+' '+text+')</font></i>' : ''; 
 

 

 
\t var month = [1,2,3,4,5,6,7,8,9,10,11,12]; 
 
\t var month2 = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; 
 

 
\t var day = postdate.split("-")[2].substring(0,2); 
 
\t var m = postdate.split("-")[1]; 
 
\t var y = postdate.split("-")[0]; 
 

 
\t for(var u2=0;u2<month.length;u2++){ 
 
\t \t if(parseInt(m)==month[u2]) { 
 
\t \t \t m = month2[u2] ; break; 
 
\t \t } 
 
\t } 
 

 
\t var daystr = day+ ' ' + m + ' ' + y ; 
 
    pcm='<a href="'+posturl+'">'+pcm+' comments</a>'; 
 
\t 
 
if (i==0) { 
 
\t var trtd = '<div class="entry-thumb"><a href="'+posturl+'"><img width="70" height="70" src="'+img[i]+'"/></a></div><h3 class="entry-title"><a href="'+posturl+'">'+posttitle+'</a></h3><div class="entry-meta"></div><div class="entry-excerpt"><p>'+removeHtmlTag(postcontent,summaryPost4)+'...</p></div>'; 
 
\t document.write(trtd); 
 
} 
 
if ((i>0)&&(i<maxpost)) 
 
    { 
 
\t var trtd = '<li class="catlist"><a href="'+posturl+'">'+posttitle+'</a></li>'; 
 
\t document.write(trtd); 
 
} 
 
\t j++; 
 
} 
 

 
} 
 

 
//]]> 
 
</script> 
 
</head> 
 

 
<body>

Y se puede ver en la demo harga lantai kayu

Cuestiones relacionadas