2009-06-11 33 views
146

Quiero llamar a una función después de cargar un documento, pero el documento puede o no haber terminado de cargarse todavía. Si se cargó, entonces puedo llamar a la función. Si NO se cargó, entonces puedo adjuntar un detector de eventos. No puedo agregar un eventlistener después de que la carga ya se haya activado, ya que no se llamará. Entonces, ¿cómo puedo verificar si el documento se ha cargado? Probé el código a continuación, pero no funciona del todo. ¿Algunas ideas?Javascript - Cómo detectar si el documento se ha cargado (IE 7/Firefox 3)

var body = document.getElementsByTagName('BODY')[0]; 
// CONDITION DOES NOT WORK 
if (body && body.readyState == 'loaded') { 
    DoStuffFunction(); 
} else { 
    // CODE BELOW WORKS 
    if (window.addEventListener) { 
     window.addEventListener('load', DoStuffFunction, false); 
    } else { 
     window.attachEvent('onload', DoStuffFunction); 
    } 
} 
+5

"Quiero llamar a una función después de cargar un documento, pero el documento puede o no haber terminado de cargarse todavía". Esto no se calcula. –

+4

Creo que quiere decir que no tiene control sobre cuándo se ejecuta inicialmente su bloque de código, pero quiere asegurarse de que DoStuffFunction() no se invoque antes de que el documento haya terminado de cargarse. –

+1

Oh, eso tiene sentido. –

Respuesta

15

Probablemente desee utilizar algo como jQuery, que hace que la programación de JS sea más fácil.

Algo así como:

$(document).ready(function(){ 
    // Your code here 
}); 

parecería que ver lo que está después.

+2

Y si quiere ver cómo jQuery lo hace de forma portátil, la fuente de jQuery está ahí para la inspección :-) –

+5

Y en caso de que no esté claro, si 'ready()' se llama * después de la carga del documento, la función aprobada se ejecuta inmediatamente. –

+1

@Ben En blanco: a menos, por supuesto, jQuery sí mismo se incluye después de que el documento ha cargado;) –

5

Si realmente desea que este código se ejecute en load, no en domready (es decir, necesita que las imágenes se carguen también), entonces desafortunadamente la función de listo no lo hace por usted. Yo por lo general acaba de hacer algo como esto:

Incluir en el documento Javascript (es decir, siempre se llama antes despedido proceso de carga):

var pageisloaded=0; 
window.addEvent('load',function(){ 
pageisloaded=1; 
}); 

Luego, su código:

if (pageisloaded) { 
DoStuffFunction(); 
} else { 
window.addEvent('load',DoStuffFunction); 
} 

(o el equivalente en su marco de preferencia.) Uso este código para hacer precaching de javascript e imágenes para páginas futuras. Como las cosas que obtengo no se usan para esta página en absoluto, no quiero que tengan prioridad sobre la descarga rápida de imágenes.

Puede haber una manera mejor, pero todavía tengo que encontrarla.

31

No hay necesidad de una biblioteca. jQuery usó este script por un tiempo, por cierto.

http://dean.edwards.name/weblog/2006/06/again/

// Dean Edwards/Matthias Miller/John Resig 

function init() { 
    // quit if this function has already been called 
    if (arguments.callee.done) return; 

    // flag this function so we don't do the same thing twice 
    arguments.callee.done = true; 

    // kill the timer 
    if (_timer) clearInterval(_timer); 

    // do stuff 
}; 

/* for Mozilla/Opera9 */ 
if (document.addEventListener) { 
    document.addEventListener("DOMContentLoaded", init, false); 
} 

/* for Internet Explorer */ 
/*@cc_on @*/ 
/*@if (@_win32) 
    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); 
    var script = document.getElementById("__ie_onload"); 
    script.onreadystatechange = function() { 
    if (this.readyState == "complete") { 
     init(); // call the onload handler 
    } 
    }; 
/*@end @*/ 

/* for Safari */ 
if (/WebKit/i.test(navigator.userAgent)) { // sniff 
    var _timer = setInterval(function() { 
    if (/loaded|complete/.test(document.readyState)) { 
     init(); // call the onload handler 
    } 
    }, 10); 
} 

/* for other browsers */ 
window.onload = init; 
+1

Exactamente lo que estaba buscando - la función jQuery.ready sin la biblioteca jQuery. Gracias! – stricjux

+3

Totalmente perdido el punto de la pregunta. 'init' no se ejecutará si el código que publicó está incluido después de que la página ya se haya cargado, que es el punto del OP: no puede controlar cuándo se incluye su secuencia de comandos. (Tenga en cuenta que solo funcionará la rama 'setInterval') –

+3

Esto pertenece a una biblioteca. Junto con todas las otras ruedas, las personas comúnmente reinventan. – b01

5
if(document.loaded) { 
    DoStuffFunction(); 
} else { 
    if (window.addEventListener) { 
     window.addEventListener('load', DoStuffFunction, false); 
    } else { 
     window.attachEvent('onload', DoStuffFunction); 
    } 
} 
+0

¡Esto funciona bien! – Ankit

234

No hay necesidad de que todo el código mencionado por galambalazs. La forma cruzada navegador para hacerlo en JavaScript puro es simplemente prueba document.readyState:

if (document.readyState === "complete") { init(); } 

Así es también como jQuery hace.

Dependiendo de donde se carga el código JavaScript, esto se puede hacer dentro de un intervalo:

var readyStateCheckInterval = setInterval(function() { 
    if (document.readyState === "complete") { 
     clearInterval(readyStateCheckInterval); 
     init(); 
    } 
}, 10); 

De hecho, document.readyState puede tener tres estados:

devuelve "carga", mientras que el documento es cargando, "interactivo" una vez que se termina de analizar, pero sigue cargando sub-recursos, y "completa" una vez que se ha cargado. - document.readyState at Mozilla Developer Network

Así que si sólo necesita el DOM para estar listo, comprobar si hay document.readyState === "interactive".Si necesita que toda la página esté lista, incluidas las imágenes, verifique document.readyState === "complete".

+0

¿ReadyState espera a que se carguen las imágenes? – Costa

+3

@costa, si 'document.readyState ==" complete "', significa que todo, incluidas las imágenes, se han cargado. –

+0

Estoy usando una combinación de ambos eventos y 'documento.readyState' para asegurarse de que la función se inicia después de que DOM se haya analizado, o más tarde, según cuándo se ha llamado. ¿Hay algún evento para * interactive * 'readyState'? –

3

El anterior con JQuery es la forma más fácil y más utilizada. Sin embargo, puede usar javascript puro, pero trate de definir este script en el encabezado para que se lea al principio. Lo que estás buscando es window.onload evento.

A continuación se muestra un script simple que he creado para ejecutar un contador. El contador se detiene después de 10 iteraciones

window.onload=function() 
{ 
    var counter = 0; 
    var interval1 = setInterval(function() 
    { 
     document.getElementById("div1").textContent=counter; 
     counter++; 
     if(counter==10) 
     { 
      clearInterval(interval1); 
     } 
    },1000); 

} 
1

tengo otra solución, necesita mi aplicación se inicie cuando se crea nuevo objeto de MiApl, por lo que parece:

function MyApp(objId){ 
    this.init=function(){ 
     //......... 
    } 
    this.run=function(){ 
      if(!document || !document.body || !window[objId]){ 
       window.setTimeout(objId+".run();",100); 
       return; 
      } 
      this.init(); 
    }; 
    this.run(); 
} 
//and i am starting it 
var app=new MyApp('app'); 

que está trabajando en todo navegadores, eso lo sé.

2

Prueba esto:

var body = document.getElementsByTagName('BODY')[0]; 
// CONDITION DOES NOT WORK 
if ((body && body.readyState == 'loaded') || (body && body.readyState == 'complete')) { 
    DoStuffFunction(); 
} else { 
    // CODE BELOW WORKS 
    if (window.addEventListener) { 
     window.addEventListener('load', DoStuffFunction, false); 
    } else { 
     window.attachEvent('onload',DoStuffFunction); 
    } 
} 
3

Mozila Firefox dice que onreadystatechange es una alternativa a DOMContentLoaded.

// alternative to DOMContentLoaded 
document.onreadystatechange = function() { 
    if (document.readyState == "complete") { 
     initApplication(); 
    } 
} 

En DOMContentLoaded de documentación de la Mozila dice:

El evento DOMContentLoaded se activa cuando el documento ha sido completamente cargada y analizada, sin esperar a que las hojas de estilo, imágenes, y subtramas para terminar de cargar (el evento de carga se puede usar para detectar una página completamente cargada).

Creo que el evento load se debe usar para cargar documentos completos.

Cuestiones relacionadas