2012-02-23 10 views
5

Estoy tratando de detectar si el archivo actual Javascript que está siendo ejecutado se incluye de forma sincrónica (a través de una etiqueta de escritura regular)Cómo detectar si su Javascript está siendo incluido de forma sincrónica o asincrónica

<script src="myscript.js"></script> 

o asincrónica a través de la inserción de una elemento de script en el DOM mediante programación, algo así como

var script = document.createElement('script') 
script.src = 'myscript.js' 
document.body.appendChild(script) 

y en consecuencia, si document.write se puede utilizar o no. He descubierto una solución loca que prueba si document.write funciona, vea this gist.

Básicamente, funciona usando document.write para escribir un elemento: elegí una etiqueta de script vacía. A continuación, consulta el DOM para determinar si ese elemento de script se escribió correctamente. Si lo fue, el script debe haberse incluido de forma síncrona, si no lo fue, se incluyó de forma asíncrona.

Esta solución funciona en todos los navegadores que he probado hasta el momento (todos los más importantes, incluido IE7 +) a excepción de Opera.

La pregunta es: ¿hay una solución mejor?

Nota: También he intentado comprobar document.readyState, pero eso no parece ser útil en IE.

También tenga en cuenta: No necesito una conferencia que document.write es malo. Lo sé.

Actualización: Resulta que además de no trabajar en la ópera, mi técnica también es poco fiable en algunos casos en IE y otros navegadores - document.write puede o no funcionar dependiendo del momento o la situación de almacenamiento en caché. El spec parece decir tanto.

+2

¿Estás seguro de que no necesitas la conferencia? Estaba todo listo para darle uno ...: P – Domenic

Respuesta

1

esto es malo, pero podría redefinir las funciones del documento y escribir las suyas propias. algo como esto quizá:

var oldAppendChild = document.body.appendChild; 

document.body.appendChild = function(child) { 
    //examine if child is a script element, do stuff with it if it is 
    //finally do what the original function did and: 
    oldAppendChild(child); 
} 

por supuesto que tendría que manejar todas las diferentes peculiaridades del navegador y ya todas las diferentes formas se podría añadir un elemento de secuencia de comandos para la página, pero es una alternativa a lo que usted describe

+0

No estoy seguro de cómo esto me ayuda a detectar cómo se incluyó el guión. – airportyh

+1

ah, parece que no entendí bien. ¿Desea que el script * execute * sepa cómo * se incluyó *? –

+0

Sí, eso es exactamente. – airportyh

1

Si tiene control total sobre todos los lados, puede usar una página de servidor dinámico para JS y parámetros de consulta en la url según sea necesario y luego usar eso para establecer una variable dentro del script.

var script = document.createElement('script'); 
script.src = 'myscript.php?type=asynch'; 
document.body.appendChild(script); 

podría ser posible hacer este lado todos los clientes mediante la comprobación de atributo "src" del elemento de secuencia de comandos, pero no soy positivo sobre eso.

+0

Sí, eso podría funcionar. El script deberá atravesar todos los elementos del script y coincidir por URL para encontrar la coincidencia. Sin embargo, espero no tener que seguir esta ruta. – airportyh

+0

Si mi respuesta fue útil o correcta, acéptala para que se me otorguen los puntos. Usted acepta haciendo clic en la marca de verificación que se muestra junto a la respuesta. –

0

Bueno, aquí hay una solución rápida y sucia. Suponemos que si el evento DOMContentLoaded se ha activado, se ha cargado todo el documento, incluidos todos los scripts. Si su script se ejecuta antes de eso, se ha ejecutado sort-of 'synchroneously' según su definición. Si se ejecuta posteriormente, debe cargarse de otra manera ('asincrónicamente').

De nuevo, rápido y sucio: en su archivo html cree una etiqueta de script en su cabeza; Para ser compatible con varios navegadores, creo que tiene que ser la primera etiqueta de script en su archivo html (nota: window.DOMready es falsey si no está definido en los navegadores modernos).

<script> 
// this property by default is false 
window.DOMready = false; 

// all browsers but IE<8 
// wait for the DOMContentLoaded event and set window.DOMready to true 
if (document.addEventListener) { 
    document.addEventListener("DOMContentLoaded", function() { 
     window.DOMready = true; 
    }, false); 

} else { 
    // not entirely accurate but functioning in IE<8 
    // you may want to use another IE solution if you care 
    window.onload = function() { 
     window.DOMready = true; 
    } 
} 
</script> 

Luego, en los archivos de secuencia de comandos puede verificar la propiedad window.DOMready. Si es verdadero, su script ha sido cargado de manera sincronizada. Ejemplo:

// myscript.js 
if (window.DOMready) { 
    // we have been loaded asynchroneously 
} else { 
    // we have been loaded synchroneously 
} 

¡Disfrútalo!

+0

Esto no funcionará realmente porque una secuencia de comandos asíncrona bien podría terminar de cargarse antes de domready, si, por ejemplo, hay una secuencia de comandos de carga lenta cerca de la parte inferior de la página. – airportyh

+0

La secuencia de comandos se puede ejecutar en cualquier momento: normalmente espera que Dom esté listo usando una biblioteca de ayuda como jquery para que pueda estar seguro de que su (s) elemento (s) objetivo (s) están de hecho en el DOM. –

Cuestiones relacionadas