Анимированные числа (полу-обратный отсчет) с JQuery? - PullRequest
0 голосов
/ 27 октября 2009

Я пытаюсь сделать числовое значение, скажем, 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, однако это очень сильно провалило весь скрипт.

Любой совет приветствуется, однако я бы предпочел не использовать большие плагины для этой, казалось бы, простой задачи.

Ответы [ 3 ]

3 голосов
/ 27 октября 2009

То, что вы делаете здесь, - это обновление DOM много раз подряд. В результате браузер будет ждать, пока вы не внесете все свои изменения, и только после этого он будет перерисовывать страницу. Таким образом, вы не увидите никаких визуальных изменений, пока число не достигнет 4000.

Да, вам нужно использовать setTimeout или setInterval / clearInterval. Или, для ясности кода, вы можете использовать плагин jQuery "wait" :

// (code to get new value goes here)

$('.class').wait(100, function(){
    $(this).text(newValue);
});

Вместо html() я использовал text(), так как, похоже, вам не нужно менять структуру HTML.

2 голосов
/ 27 октября 2009

Когда я запустил код, который вы указали, я попал в бесконечный цикл. В конце цикла 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);
    }
}
0 голосов
/ 27 октября 2009

Мне нравится подход Торна с 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, в другом случае. Вы должны убедиться, что этого не произойдет до вызова функции.

...