2010-08-14 4 views
5

Estoy reconstruyendo mi módulo cargador perezoso para aceptar la solicitud asyncronus pero tengo un GRAN problema:
Internet Explorer no es compatible con script.onload/onerror !!!secuencia de comandos onload/onerror con IE (para la carga diferida) problemas

El guión de edad se eval a nivel mundial la fuente de escritura de término de leer con una llamada de sincronización ajax, funciona muy bien, es el navegador cruz y que puede hacer que sea asíncrono edición de 1 variable, pero es muy difícil de depuración (todo el código fuente se ejecuta en una sola línea y el navegador da no mucha información sobre los errores, dividir el código por línea con una expresión regular es IMPOSIBLE porque js tiene bloques con profundidad infinita y expresiones regulares simplemente no son buenas en esto).

Este es el código que utilizo para crear la secuencia de comandos (un clásico):

var script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.src =name; 
script.name =name; 
script.async = true; 
script.onload=<my_onload_code>; 
script.onerror=<my_onerror_code>; 

no funcionará en IE porque doesen't apoyo onload y onerror con el guión;
el código de abajo es una solución, pero sólo funciona si el guión no es asíncrono

if(script.onreadystatechange!==undefined)//only IE T_T 
      script.onreadystatechange = function() { 
        if (script.readyState == 'loaded')//ERROR LOADING 
         <my_onerror_code>; 
        else 
        if(script.readyState == 'complete')//loaded 
         <my_onload_code>; 

      }; 

puedo probar que cada X milisegundos hasta que se cargue el guión pero es una solución fea y quiero evitarlo.

EDIT: este es el código i tryed para comprobar cada X ms si se carga el guión, no es tan malo y que funciona mejor que el Ajax, el problema es que no puedo saber si el guión está cargado con éxito o con error (onload o onerror).

var script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.src =name; 
script.name =name; 
script.async = true; 

    script.onload=function(){Lazy_loader.onload(this);}; 
    script.onerror=function(){Lazy_loader.onerror(this);}; 

    if(script.onreadystatechange!==undefined){//ie fix T_T 
     script.timer=setInterval(function(){ 
        if (script.readyState == 'loaded' || script.readyState == 'complete')}//ERROR LOADING 

         if(LOADED???)//loaded 
          Lazy_loader.onload(script); 
         else 
          Lazy_loader.onerror(script); 

         clearInterval(script.timer); 
        } 

        },100); 

    } 

document.getElementsByTagName('head')[0].appendChild(script); 

He probado a utilizar las funciones/attachEvent addEventListener pero no parece que trabajar (incluso utilizando funciones addEvent desde la web)

que resume las opciones parece ser:

  • Uso AJAX y global eval para cargar el script (depuración infierno)
  • Usar AJAX y evaluación global solo con IE (puede ser una solución, no uso IE)
  • Usar AJAX y gl obal eval solo si la secuencia de comandos contiene errores (necesito verificar los problemas de temporizaciones porque con mi código "simulo" código sincrónico incluso si la llamada es asíncrona)
  • Pruebe script.onreadystatechange (solo en IE) cada X veces hasta que se cargue (FEO !!!)
  • Use window.onload: EVITAR, tiene que cargar TODA la página, necesito llamarlo cuando SOLO se inicia un script (ver detalles en la página final)
  • Agregar un código a la fuente de cada script (evite dicho como en endpage)
  • fijar el script.onload para IE (mediante addEventListener/attachEvent?!?)


ATENCIÓN:
no quiero usar window.onload porque se activa solo cuando se carga TODA la página, necesito activarlo cuando solo se carga el script de destino (mi script de carga lenta es un mucho más complejo así que por favor no preguntes por qué);
NO QUIERO usar CUALQUIER biblioteca de terceros (como jquery, prototype, etc.),
ni siquiera quiero editar el origen del script de destino (como cuando se usa JSPON o se agrega un script para alertar que el script está cargado).

Espero que no sea demasiado! Gracias.

+1

De acuerdo con msdn, el script admite la carga http://msdn.microsoft.com/en-us/library/cc197055%28VS.85%29.aspx – mplungjan

+0

pruébelo, no funcionará. es como tratar de modificar el contenido de una etiqueta

0

ignore la basura a continuación. la siguiente cosa de hermanos fue el resultado de estar en el depurador y no fue realmente reproducible en el mundo real. en su lugar, tendría que recomendar visitar www.requirejs.org

que proporciona un método que es lo más parecido a una declaración de inclusión o importación que se puede encontrar en js.

esto es una solución totalmente tonta, y voy a seguir este hilo para comentarios sobre por qué esto funciona, pero aquí va cómo lo arreglé sin un temporizador.

var url = load_obj.url; 
var callback = load_obj.callback; 
var head = document.getElementsByTagName('head')[0]; 
var appendage; 
var complete = false;
appendage = document.createElement('script'); appendage.type = 'text/javascript'; appendage.onload = appendage.onreadystatechange = function() { if (!complete && (!this.readyState || this.readyState === 'complete' || (this.readyState === 'loaded' && this.nextSibling != null))) { console.log('loaded via all'); complete = true; if (callback) callback(); //remove listeners appendage.onload = appendage.onreadystatechange = null; } else if (this.readyState === 'loaded' && this.nextSibling == null) { console.log('error via ie'); } appendage.onerror = function() { console.log('error via everything else'); } appendage.src = url;

como dije no sé POR QUÉ nextSibling es nulo en un intento 404, pero si la URL js era correcta, nextSibling tenía un valor.

+0

después de más pruebas, esto parece funcionar mientras se depura - después de romper en el if (! complete ... statement. – prodaea

+0

Estoy dispuesto a apostar que nextSibling es nulo porque el elemento script de 404 es lo último que se agrega a la cabeza en tu prueba. – Borgar

1
script.onreadystatechange = function() { 
    if (script.readyState == 'loaded')//ERROR LOADING 
     <my_onerror_code>; 
    else if(script.readyState == 'complete')//loaded 
     <my_onload_code>; 

}; 

tengo que decir que, independientemente de si async se ajusta o no, usando readyState = 'loaded' para comprobar el error no es suficiente. De hecho, loaded se activará en situaciones que carguen el script de error o la primera vez que cargue el script correcto.

Puede agregar src con cadena de consulta aleatoria para deshabilitar la memoria caché, luego marque readyState.

Cuestiones relacionadas