2010-02-17 10 views
5

Necesito hacer algo como esto:Javascript escritura del bloque de ejecución

  • Ejecutar una pieza de código
  • de inicio para cargar una imagen y bloquear la ejecución del script
  • Cuando la imagen se carga de reanudación de la ejecución
  • Ejecutar el resto del código

sé que la forma más sencilla es asignar una función en el proceso de carga de la imagen de una Luego, ejecute el resto del código en la función, pero si es posible, quiero tener un comportamiento "lineal" que bloquee la ejecución del script y luego reanudarlo. Entonces, ¿hay una forma de navegador cruzado para hacer esto?

Respuesta

3

La única manera de bloquear la ejecución del script es utilizar un bucle, que también encerrar a la mayoría de los navegadores y prevenir cualquier interacción con su página web.

Firefox, Chrome, Safari, Opera e IE todos admiten la propiedad complete, que finalmente se estandarizó en HTML5. Esto significa que puede usar un bucle while para detener la ejecución del script hasta que la imagen haya terminado de descargarse.

var img = new Image(); 
img.src = "/myImage.jpg"; 
document.body.appendChild(img); 
while (!img.complete) 
{ 
    // do nothing... 
} 

// script continues after image load 

Dicho esto, creo que debe buscar formas de lograr su objetivo sin bloquear el navegador.

+0

Estoy de acuerdo en que esta es una mala manera, pero también creo que es la única forma. Tal vez pueda darle al usuario la posibilidad de elegir entre bloquear la ejecución del script y llamar a la función de carga cuando se carga la imagen. – mck89

+0

@ mck89: Me cuesta creer que sea la única forma. Honestamente puedo decir que nunca he encontrado una situación en JavaScript que requiera bloquear el script; siempre hay una forma (como anular funciones temporalmente) para hacer cosas de manera asincrónica. Usted tiene el control del guión en su página, después de todo. ¿Tal vez podrías publicar otra pregunta para más detalles sobre tu problema? –

+0

@ mck89: la propiedad 'complete' existe para Gecko e IE y podría funcionar también en otros navegadores. Si insiste en bloquear la ejecución de scripts, vea mi actualización. –

1

Si no te importa tener un paso de procesamiento previo, tratar Narrative Javascript, que se puede

image.onload = new EventNotifier(); 
image.onload.wait->(); 
+0

Ese es un gran proyecto, pero estoy tratando de crear una aplicación simple en javascript puro ... y no sé nada de Java :) – mck89

+0

@ mck89: Después del preprocesamiento, obtienes Javascript puro. – kennytm

+0

Sí, lo sé, pero prefiero usar solo javascript – mck89

1

Esta sugerencia no es exactamente la que usted solicitó, pero la ofrezco como una posible alternativa.

Crea una clase de CSS con la imagen de fondo que deseas usar. Cuando se inicia la aplicación, asigne esta clase de CSS a un DIV que esté oculto fuera del sitio o tenga un tamaño de cero por cero píxeles. Esto asegurará que la imagen se cargue desde el servidor. Cuando desee cargar la imagen (paso dos arriba), use la clase CSS que cree; esto sucederá rápidamente ¿Tal vez lo suficientemente rápido como para no bloquear la siguiente ejecución del código?

+0

Sí, este podría ser un buen método de precarga para las imágenes, pero no estoy cargando la imagen al principio de la aplicación. – mck89

+0

Lo entiendo, pero si creaste una clase CSS con un atributo background-image, asignó esa clase a un DIV ficticio, estarías cargando la imagen al principio de la aplicación. – Upperstage

1

No intentaría bloquear la ejecución de scripts por completo, ya que eso podría ralentizar el navegador o incluso alertar al usuario de que un script tarda demasiado en ejecutarse.

Lo que puede hacer es "linealizar" su código mediante el uso de eventos para terminar el trabajo. Tendrá que agregar un tiempo de espera a la función, ya que la imagen puede que nunca se cargue.

Ejemplo:

var _img = null; 
var _imgDelay = 0; 
var _finished = false; 

function startWork(){ 
    _img = document.createElement('img'); 
    _img.onload = onImgLoaded; 
    _img.src = 'yourimg.png'; 

    // append img tag to parent element here 

    // this is a time out function in case the img never loads, 
    // or the onload event never fires (which can happen in some browsers) 
    imgTimeout(); 
} 

function imgTimeout(){ 
    if (_img.complete){ 
     // img is really done loading 
     finishWork(); 
    } 
    else{ 
     // calls recursively waiting for the img to load 
     // increasing the wait time with each call, up to 12s 
     _imgDelay += 3000; 

     if (_imgDelay <= 12000){ // waits up to 30 seconds 
     setTimeout(imgTimeout, _imgDelay); 
     } 
     else{ 
     // img never loaded, recover here. 
     } 
    } 
} 

function onImgLoaded(){ 
    finishWork(); 
} 

function finishWork(){ 
    if (!_finished){ 
     // continue here 
     _finished = true; 
    } 
} 
+0

¿Estás seguro de que puedes detener la ejecución con setTimeout? – mck89

+0

Esto no detiene la ejecución del código, le permite esperar hasta que la imagen termine de cargarse antes de hacer más trabajo. Usted 'detiene' la ejecución de su propio código moviendo el código restante a la función finishWork. – FlashXSFX

1

Puede utilizar xmlhttprequest y utilizar el modo sincrónico.

var url = "image.php?sleep=3"; 
var img = new Image; 
var sjax = new XMLHttpRequest(); 
img.src = url; 
sjax.open("GET", url, false); 
sjax.send(null); 
alert(img.complete); 

El truco aquí es cargamos la misma imagen dos veces, primero utilizando el objeto Image, y también por el uso de AJAX en modo síncrono. El objeto Image no es necesario, simplemente asumí que así es como quieres cargarlo. Sin embargo, la clave es que si se completa ajax, la imagen se descargará por completo y se guardará en el caché del navegador. Como tal, la imagen también estará disponible para su uso en el objeto Image.

Esto supone que la imagen se sirve con encabezados http compatibles con caché. De lo contrario, su comportamiento puede variar en diferentes navegadores.

Cuestiones relacionadas