Анимированные числа (полу-обратный отсчет) с JQuery?
-
06-07-2019 - |
Вопрос
Я пытаюсь сделать числовое значение, скажем, 5000, быстро изменить на другое значение, скажем, 4000, используя JQuery. Прямо сейчас я делаю это нормально, используя:
mod(".class",4000,"add");
function mod(id,value,type){
var numb = $(id).html();
var current_value = parseInt(numb);
do {
if(type == "add")
increment(id);
else
decrement(id);
current_value = parseInt(numb);
}while(current_value != value);
function decrement(id){
$(id).html(current_value-1);
}
function increment(id){
$(id).html(current_value+1);
}
}
Я знаю, что это, вероятно, не лучший способ сделать это, но мне нужно, чтобы он сделал очень быстрый обратный отсчет (или увеличение) чисел от текущего значения до заданного значения. С помощью этого метода я намеревался задержать использование setInterval или setTimeout, однако это привело к серьезному провалу всего сценария.
Любой совет приветствуется, однако я бы предпочел не использовать большие плагины для этой, казалось бы, простой задачи.
Решение
Когда я запустил предоставленный вами код, я попал в бесконечный цикл. В конце цикла do у вас есть
current_value = parseInt (numb);
но значение numb устанавливается только в начале функции, поэтому оно продолжается вечно. Если вы измените это на
current_value = parseInt ($ (id) .html ());
тогда все работает нормально. За исключением того, что это происходит мгновенно.
Я взломал метод для достижения анимации с использованием тайм-аутов, который, кажется, работает довольно хорошо, но, поскольку я все еще довольно плохо знаком с javascript, я не знаю, существует ли более эффективный подход или нет. Просто настройте второй параметр, передаваемый setTimeout, чтобы получить желаемую скорость. И если вы хотите изменить значение приращения / уменьшения, просто измените замедление на dir
.
function mod2(id, value) {
var numb = $(id).html();
var current_value = parseInt(numb);
// determine direction to go
var dir = 1;
if (current_value - value > 0) {
dir *= -1;
}
getThere(id, current_value, value, dir);
}
function getThere(id, current_value, target_value, dir) {
current_value += dir;
$(id).html(current_value);
if (current_value != target_value) {
setTimeout("getThere('"+id+"',"+current_value+","+target_value+","+dir+")", 10);
}
}
Другие советы
То, что вы делаете здесь, - это обновление DOM много раз подряд. В результате браузер будет ждать, пока вы не внесете все свои изменения, и только после этого он будет перерисовывать страницу. Таким образом, вы не увидите никаких визуальных изменений, пока число не достигнет 4000.
Да, вам нужно использовать setTimeout
или setInterval
/ clearInterval
. Или, для ясности кода, вы можете использовать jQuery " wait " плагин :
// (code to get new value goes here)
$('.class').wait(100, function(){
$(this).text(newValue);
});
Вместо html ()
я использовал text ()
, так как, похоже, вам не нужно менять структуру HTML.
Мне нравится подход Thorn с setTimeout, но я бы сжал его до 2 функций и запустил после загрузки окна, чтобы убедиться, что страница загружена до обновления счетчика:
var counterTimeout = 10; // time between increments in ms
$(window).load(function() {
mod('class', 'add', 4000);
});
function mod(class, type, targetVal) {
var $class = $(class);
var numb = parseInt($class.html());
numb = (type == 'add') ? numb + 1 : numb - 1;
$class.html(numb);
if (numb != targetVal) {
setTimeout('mod("' + class + '","' + type + '",' + targetVal)', counterTimeout);
}
}
Базовый случай не выполняется в случае, когда $ class.html () начинается со значения, большего, чем targetVal в случае 'add', или ниже, чем targetVal, в другом случае. Вы должны убедиться, что этого не произойдет до вызова функции.