2008-10-15 9 views
8

tengo una función de javascript del lado del cliente que se activa con un clic de botón (básicamente, es una calculadora !!). A veces, debido a la gran cantidad de datos en la página, la función de calculadora de JavaScript lleva a long & hace que la página parezca inactiva para el usuario. Estaba planeando mostrar una div transparente en toda la página, tal vez con un indicador de ocupado (en el centro) hasta que la función de la calculadora termine, de modo que el usuario espere hasta que el proceso finalice.Javascript - indicador de carga/ocupado o div transparente sobre la página en el evento clic

 
function CalculateAmountOnClick() { 
    // Display transparent div 

    // MY time consuming loop! 
    { 

    } 

    // Remove transparent div 

} 

¿Alguna idea de cómo hacerlo? ¿Debo asignar una clase css a un div (que rodea el contenido de toda mi página) usando javascript cuando se inicia mi función de calculadora? Intenté eso pero no obtuve los resultados deseados. Estaba enfrentando problemas con la transparencia en IE 6. Además, ¿cómo mostraré un mensaje de carga + imagen en un div tan transparente?

TIA

Respuesta

11

Javacript para mostrar una cortina:

function CalculateAmountOnClick() { 
    var curtain = document.body.appendChild(document.createElement('div')); 
    curtain.id = "curtain"; 
    curtain.onkeypress = curtain.onclick = function(){ return false; } 
    try { 
    // your operations 
    } 
    finally { 
    curtain.parentNode.removeChild(curtain); 
    } 
} 

Su CSS:

#curtain { 
    position: fixed; 
    _position: absolute; 
    z-index: 99; 
    left: 0; 
    top: 0; 
    width: 100%; 
    height: 100%; 
    _height: expression(document.body.offsetHeight + "px"); 
    background: url(curtain.png); 
    _background: url(curtain.gif); 
} 

(Mover MSIE 6 subrayado hacks para incluida condicionalmente archivos como desee.)

Se puede instalar esto como añadir/quitar funciones de la cortina, o como un envoltorio:

function modalProcess(callback) { 
    var ret; 
    var curtain = document.body.appendChild(document.createElement('div')); 
    curtain.id = "curtain"; 
    curtain.onkeypress = curtain.onclick = function(){ return false; } 
    try { 
    ret = callback(); 
    } 
    finally { 
    curtain.parentNode.removeChild(curtain); 
    } 
    return ret; 
} 

que luego se podría llamar así:

var result = modalProcess(function(){ 
    // your operations here 
}); 
2

me gustaría hacer algo como:

1.unhide un div (display: inline)

2.make la posición: absoluta

3.give un z -índice: 99

4.Make la altura y la anchura 100%

5. Cuando el proceso se hace de pantalla establecido: ninguno

Para hacerlo más transparente que tendrá que establecer la opacidad que es diferente en FF es decir, etc.

Para mostrar un icono de carga siempre se puede crear una segunda div y colóquelo donde desee en la página. Cuando termine de cargarse, quítelo junto con el transparente.

+0

en mi caso, el punto 4 no funcionó. A través de jQuery hice que el ancho y el alto del div sean los de los padres, ¡y todo funciona muy bien !. Otros puntos completamente bien! – Neonamu

0

Además de todo lo anterior, no olvide poner un iframe invisible detrás de la cuña, para que aparezca arriba de los cuadros de selección en IE.

Editar: Este sitio, aunque proporciona una solución a un problema más complejo, cubre la creación de un fondo modal. http://www.codeproject.com/KB/aspnet/ModalDialogV2.aspx

0

Para el mensaje de carga, me gustaría utilizar un <div> con position:absolute, posicionarlo usando left y top, y ajustar la pantalla a none.

Cuando desee mostrar el indicador de carga, tendrá que usar un tiempo de espera de div que no se mostrará hasta que finalice su procesamiento. Por lo tanto, se debe modificar el código para esto:

function showLoadingIncidator() 
{ 
    // Display div by setting display to 'inline' 

    setTimeout(CalculateAmountOnClick,0); 
} 

function CalculateAmountOnClick() 
{ 
    // MY time consuming loop! 
    { 

    } 

    // Remove transparent div 
} 

Debido a que se establece el tiempo de espera, la página se volverá a dibujar antes de que ocurra el bucle de tiempo.

5

yo voy para hacer algunas suposiciones pesadas aquí, pero me parece que lo que está sucediendo es que, debido a que está bloqueando directamente el navegador con un procesamiento intenso inmediatamente después de haber configurado el elemento de la cortina, el navegador nunca tiene la oportunidad de sacar la cortina.

El navegador no se vuelve a dibujar cada vez que actualiza el DOM. Puede sentirse mal si está haciendo algo más y luego dibuja lo que necesita (los navegadores varían su método para esto). Por lo tanto, en este caso, puede refrescar la pantalla solo después de haber quitado la cortina, o ha forzado un redibujado desplazándose.

Una advertencia justa: este tipo de procesamiento intenso no es muy amable de su parte, ya que no solo bloquea su página. Debido a que los navegadores generalmente implementan solo una única secuencia de Javascript para TODAS las pestañas, su procesamiento bloqueará todas las pestañas abiertas (= el navegador). Además, se corre el riesgo de que el tiempo de espera de ejecución y el navegador simplemente detengan su script (esto puede ser de tan solo 5 segundos).

Aquí hay una forma de evitarlo.

Si puede dividir el procesamiento en trozos más pequeños, puede ejecutarlo con un tiempo de espera (para permitir que el explorador respire espacio). Algo como esto debería funcionar:

function processLoop(actionFunc, numTimes, doneFunc) { 
    var i = 0; 
    var f = function() { 
    if (i < numTimes) { 
     actionFunc(i++); // closure on i 
     setTimeout(f, 10) 
    } 
    else if (doneFunc) { 
     doneFunc(); 
    } 
    }; 
    f(); 
} 

// add a curtain here 
processLoop(function (i){ 
    // loop code goes in here 
    console.log('number: ', i); 
}, 
10, // how many times to run loop 
function(){ 
    // things that happen after the processing is done go here 
    console.log('done!'); 
    // remove curtain here 
}); 

Se trata esencialmente de un bucle de tiempo, pero cada iteración del bucle se realiza en un intervalo de tiempo para que el navegador tiene un poco de tiempo para respirar en el medio. Sin embargo, ralentizará el procesamiento, y cualquier trabajo posterior deberá pasar a una devolución de llamada ya que el ciclo se ejecuta independientemente de lo que pueda seguir la llamada a processLoop.

Otra variación de esto es configurar la cortina, llamar a su función de procesamiento con un setTimeout para permitir que el navegador abra la cortina, y luego eliminarla una vez que haya terminado.

// add a curtain 
var curtain = document.body.appendChild(document.createElement('div')); 
curtain.id = "curtain"; 
curtain.onkeypress = curtain.onclick = function(){ return false; } 
// delay running processing 
setTimeout(function(){ 
    try { 
    // here we go... 
    myHeavyProcessingFunction(); 
    } 
    finally { 
    // remove the curtain 
    curtain.parentNode.removeChild(curtain); 
    } 
}, 40); 

Si está utilizando una biblioteca js, es posible que desee ver una solución preparada para crear cortinas. Estos deberían existir para la mayoría de las bibliotecas, here is one for jQuery, y pueden ayudar con el CSS.

Cuestiones relacionadas