Il titolo della domanda esprime ciò che ritengo sia l'ultima domanda dietro il mio caso particolare.forzare il DOM ridisegnare con javascript su richiesta
Il mio caso: All'interno di un gestore di clic, desidero rendere visibile un'immagine (un'animazione di caricamento) subito prima dell'avvio di una funzione di occupato. Quindi voglio renderlo di nuovo invisibile dopo che la funzione è stata completata. Invece di quello che mi aspettavo, mi rendo conto che l'immagine non diventa mai visibile. Immagino che ciò sia dovuto al fatto che il browser attende che il gestore termini, prima che possa eseguire qualsiasi ridisegno (sono sicuro che ci sono buone ragioni per farlo).
Il codice (anche in questo violino: http://jsfiddle.net/JLmh4/2/)
html:
<img id="kitty" src="http://placekitten.com/50/50" style="display:none">
<div><a href="#" id="enlace">click to see the cat</a> </div>
JS:
$(document).ready(function(){
$('#enlace').click(function(){
var kitty = $('#kitty');
kitty.css('display','block');
// see: http://unixpapa.com/js/sleep.html
function sleepStupidly(usec)
{
var endtime= new Date().getTime() + usec;
while (new Date().getTime() < endtime)
;
}
// simulates bussy proccess, calling some function...
sleepStupidly(4000);
// when this triggers the img style do refresh!
// but not before
alert('now you do see it');
kitty.css('display','none');
});
});
ho aggiunto la chiamata alert
subito dopo la funzione sleepStupidly
per dimostrare che in quel momento di riposo, il browser si ridisegna, ma non prima. Mi aspettavo innocentemente che si ridisegnasse subito dopo aver impostato il "display" su "block";
Per la cronaca, ho anche provato ad aggiungere tag html o a scambiare classi css, invece dell'immagine che mostra e nasconde in questo codice. Stesso risultato
Dopo tutte le mie ricerche, penso che ciò di cui ho bisogno è la capacità dello di forzare il browser a ridisegnare e interrompere ogni altra cosa fino ad allora.
È possibile? È possibile in un modo crossbrowser? Qualche plugin che non sono riuscito a trovare, forse ...?
Ho pensato che forse qualcosa come "callback jquery css" (come in questa domanda: In JQuery, Is it possible to get callback function after setting new css rule?) avrebbe fatto il trucco ... ma non esiste.
Ho anche provato a separare la visualizzazione, la chiamata di funzione e nascondere in diversi gestori per lo stesso evento ... ma niente. Inoltre, aggiungere setTimeout
per ritardare l'esecuzione della funzione (come consigliato qui: Force DOM refresh in JavaScript).
Grazie e spero che aiuti anche gli altri.
javier
EDIT (dopo aver impostato la mia risposta preferita):
Giusto per spiegare ulteriormente il motivo per cui ho scelto la strategia window.setTimeout. Nel mio caso d'uso reale ho capito che per dare al browser tempo sufficiente per ridisegnare la pagina, dovevo dargli circa 1000 millisecondi (molto più del 50 per l'esempio del violino). Questo credo sia dovuto ad un albero DOM più profondo (di fatto, inutilmente profondo). L'approccio setTimeout consente di farlo.
Non ha funzionato 'window.setTimeout()'? –
Non dovrebbe essere necessario per utilizzare un timeout più lungo. Quello di cui hai bisogno è probabilmente solo per precaricare la tua immagine per poterla mostrare immediatamente. –
Vedo. Ma capisco che sarebbe il caso se l'immagine non venisse caricata dal browser (cosa sarebbe ragionevole dato che è "display: none", immagino). Questo non è il caso, almeno con Chrome che carica l'immagine fin dall'inizio (visto con gli strumenti di sviluppo). Penso ancora sia dovuto al markup legacy con cui sto lavorando (un sacco di tabelle incorporate, davvero ... non dipendenti da me!). In realtà Firefox fa meglio (ha bisogno di 'meno tempo') ... ha senso? grazie ancora. saluti – javigzz