2012-02-26 9 views
28

Estoy tratando de ayudar a desarrollar una biblioteca y estoy tratando de trabajar con la carga de la página.
En el proceso, quiero hacer que la biblioteca sea completamente compatible con el uso de defer y async.Cómo detectar si DOMContentLoaded fue despedido

Lo que quiero es simple:
¿Cómo puedo saber que DOMContentLoaded se activó cuando se ejecuta el archivo?

¿Por qué es esto tan difícil?
En IE, document.readyState muestra interactiva antes de DOMContentLoaded.
I no utilizará detección de navegador de ninguna manera, es contrario a la política de mí y el resto de los participantes.

¿Cuál es la alternativa correcta?

Editar:

parece que no era lo suficientemente clara. Estoy no interesado en saber si el evento de carga ya ha ocurrido !!! ¡Ya sabía cómo resolver ese problema! ¡Quiero saber cómo resolver con DOMContentLoaded!

+0

Establezca un receptor que establece una propiedad o variable. Si está configurado, el evento ha sido enviado. Por supuesto, podría estar en un navegador que no admite el evento, en cuyo caso nunca ocurrirá. – RobG

+0

@RobG Ya tuve la respuesta para los navegadores, el ado no admite DOMContentLoaded. Para aquellos, uso el evento load y el evento onload. Todavía no tengo la respuesta para la pregunta que hice – brunoais

+0

No hay evento "onload", hay un atributo/propiedad * onload * para configurar oyentes para el evento * load *. Si desea saber inequívocamente si DOMContentLoaded ha ocurrido, configure un oyente y vea si se ha llamado. – RobG

Respuesta

29

Me gustaría pensar que podría utilizar:

if (document.readyState === "complete" || document.readyState === "loaded") { 
    // document is already ready to go 
} 

Esto ha sido apoyado en IE y webkit durante mucho tiempo. Fue agregado a Firefox en 3.6. Aquí está el spec. "loaded" es para navegadores Safari anteriores.

Si usted quiere saber cuando la página se ha analizado, pero todos subresources aún no se han cargado, puede agregar el valor "interactivo":

if (document.readyState === "complete" 
    || document.readyState === "loaded" 
    || document.readyState === "interactive") { 
    // document has at least been parsed 
} 

Más allá de esto, si realmente sólo quiere saber cuándo DOMContentLoaded ha disparado, entonces tendrá que instalar un controlador de eventos para eso (antes de que se dispare) y establecer un indicador cuando se dispare.

This MDN documentation es también una muy buena lectura sobre la comprensión de los estados DOM.

+0

Usted no está respondiendo la pregunta. Quiero saber sobre el evento DOMContentLoaded, no cargar evento. El evento load es fácil, el DOMContentLoaded no lo sé. – brunoais

+1

@brunoais - luego instala un controlador para el evento DOMContentLoaded y establece un indicador cuando se activa. No creo que haya otra opción. – jfriend00

+1

Si desea incluir cuando se ha analizado el documento, pero aún se están cargando sub-recursos, también puede verificar si es "interactivo". Vea el segundo ejemplo que agregué a mi respuesta. – jfriend00

1

probar este o buscar en este link

<script> 
    function addListener(obj, eventName, listener) { //function to add event 
     if (obj.addEventListener) { 
      obj.addEventListener(eventName, listener, false); 
     } else { 
      obj.attachEvent("on" + eventName, listener); 
     } 
    } 

    addListener(document, "DOMContentLoaded", finishedDCL); //add event DOMContentLoaded 

    function finishedDCL() { 
     alert("Now DOMContentLoaded is complete!"); 
    } 
</script> 

Nota

Si usted tiene un <script> después de un <link rel="stylesheet" ...>

la página no va a terminar análisis - y DOMContentLoaded no se dispara - hasta que se cargue la hoja de estilo

+1

Buen intento, pero eso no funciona después de lo que realmente estoy buscando. Eso no comprueba si el evento ya se activó, eso solo verifica si el evento se está disparando. Sé cómo comprobar si el evento se está disparando, pero no sé cómo comprobar si el evento ya se ha activado – brunoais

0

Si usted quiere saber "exactamente" si DOMContentLoaded fue despedido, se puede utilizar un indicador booleano como esto:

var loaded=false; 
document.addEventListener('DOMContentLoaded',function(){ 
loaded=true; 
... 
} 

y después con:

if(loaded) ... 
+0

Buen intento :). Sin embargo, esa no es realmente una respuesta. Como quiero que funcione correctamente con todos los navegadores (principales) y con async y diferir, no puedo estar tan seguro de que funcione como se espera debido a IE. – brunoais

+0

IE no es un navegador: D – deviato

+0

Deseamos que <_ <... – brunoais

8

El document.readyState se cambia cuando se dispara este evento . Para que pueda verificar el valor readyState y de esta manera saber si el evento se activó o no. He aquí un código para ejecutar start() cuando el documento está listo para ello:

if (/comp|inter|loaded/.test(document.readyState)){ 
    // In case DOMContentLoaded was already fired, the document readyState will be one of "complete" or "interactive" or (nonstandard) "loaded". 
    // The regexp above looks for all three states. A more readable regexp would be /complete|interactive|loaded/ 
    start(); 
}else{ 
    // In case DOMContentLoaded was not yet fired, use it to run the "start" function when document is read for it. 
    document.addEventListener('DOMContentLoaded', start, false); 
} 
+0

explique cómo funciona eso – brunoais

+0

@brunoais NP, he agregado explicaciones como comentarios, ¿está más claro ahora? – oriadam

+0

Entonces ... ¿básicamente eligió la respuesta de friend00 y construyó una respuesta con los datos de su respuesta? – brunoais

-3

Aquí está la cosa, si alguna otra biblioteca (como jQuery) ya se utiliza DOMContentLoaded, no se puede volver a usar. Eso puede ser una mala noticia, porque terminas sin poder usarlo. Vas a decir, ¿por qué no solo usas $(document).ready(), porque, NO !, no todo necesita usar jQuery, especialmente si se trata de una biblioteca diferente.

+1

No es cierto que no pueda tener múltiples oyentes de eventos. Lea en https://developer.mozilla.org/en-US/docs/DOM/document.addEventListener y en el patrón Publish/Subscribe (pub sub): https://msdn.microsoft.com/en-us/ library/ff649664.aspx – dotnetCarpenter

Cuestiones relacionadas