Проблема в том, что вы обновляете lastGrade
до истечения времени ожидания. На самом деле это влияло как на анимацию увеличения, так и на понижение, но было более заметно на уменьшающейся анимации.
Более функциональный пример здесь: http://jsfiddle.net/MrywR/
Однако вы, вероятно, захотите настроить код таким образом, чтобы в качестве индикатора анимации использовался lastGrade
, чтобы полоса не подпрыгивала.
Измененный код:
setTimeout( function updateProgress() {
x.style.width = i*1.5 + 'px';
s.innerHTML = i + '%';
if(lastGrade <= grade) {
if (i < grade){
setTimeout(updateProgress, 10);
} else {
lastGrade = grade;
}
i++;
}
else if(lastGrade > grade) {
if (i > grade){
setTimeout(updateProgress, 10);
} else {
lastGrade = grade;
}
i--;
}
}, 10);
Обновление
Эта версия в целом лучше обрабатывает анимацию: http://jsfiddle.net/5yeP7/1/
Он обрабатывает быстрый ввод, удаляет некоторые ненужные замыкания и инкапсулирует методы в качестве локальных переменных.