La seule façon de s'assurer que l'animation se produit réellement est que longRunningMethod
cède périodiquement au navigateur. Il n'est pas rare que le thread de rendu de l'interface utilisateur bloque sur le thread JavaScript. Par conséquent, les modifications apportées au DOM ne sont pas affichées avant la prochaine exécution du thread JavaScript. Vous pouvez céder en appelant setTimeout
avec un délai d'expiration de 0
(qui sera plus long que 0ms — évidemment — sur la plupart des implémentations de navigateurs, beaucoup pince cette valeur à au moins 4ms et peut-être jusqu'à 10ms).
Exemple: Voici un script qui ajoute 500 divs, mais donne le navigateur aucune occasion de montrer les travaux en cours ou (généralement) animer quoi que ce soit:
jQuery(function($) {
$("#btnGo").click(function() {
var n;
display("Loading...");
for (n = 0; n < 500; ++n) {
$("<div/>").html("Div #" + n).appendTo(document.body);
}
display("Done loading");
function display(msg) {
$("<p/>").html(msg).appendTo(document.body);
}
});
});
Live example * Example with spinner graphic
Comme vous pouvez voyez, il ne cède jamais, et donc quand vous cliquez sur le bouton, la page se bloque pendant un moment, puis tous les 500 divs et les messages apparaissent.
contraste avec cette autre extrémité du spectre, ce qui donne entre chaque div:
jQuery(function($) {
$("#btnGo").click(function() {
display("Loading...");
addDivs(0, 500, function() {
display("Done loading");
});
function addDivs(current, max, callback) {
if (current < max) {
$("<div/>").html("Div #" + current).appendTo(document.body);
setTimeout(function() {
addDivs(current + 1, max, callback);
}, 0);
}
else {
callback();
}
}
function display(msg) {
$("<p/>").html(msg).appendTo(document.body);
}
});
});
Live example * Example with spinner graphic
Depuis que les rendements, vous pouvez voir les travaux en cours.
Vous remarquerez peut-être que le deuxième script prend plus de temps, peut-être beaucoup plus longtemps, en temps réel pour atteindre le même résultat. C'est parce que les rendements prennent du temps, tout comme le navigateur qui met à jour l'affichage. En pratique, vous aurez besoin de trouver un équilibre entre le premier exemple et le second — quelque chose qui donne assez souvent pour montrer le progrès, mais pas si souvent que le processus prend un temps inutilement long à terminer.
[Ne faites pas cela alors] (http://www.jargon.net/jargonfile/d/Dontdothatthen.html). Vous savez que JavaScript n'est pas multithread, n'est-ce pas? –
Je le sais, mais il doit y avoir des moyens de le faire. – mrjohn
Que fait 'showAnimatedGif()'? Que fait 'longRunningMethod()'? Pouvez-vous poster plus de code? – karim79