Pergunta

Eu estou tentando fazer um valor numérico, digamos 5000, mudar rapidamente para outro valor, digamos, 4000, usando JQuery. Agora eu faço isso muito bem usando:

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);
    }
}

Eu sei que não é provavelmente a melhor maneira de ir sobre isso, mas o que eu preciso para que ele faça é contagem decrescente (ou para cima) os números muito rapidamente a partir do valor atual para o valor definido. O que eu pretendia com este método era ter um atraso usando setInterval ou setTimeout, porém, que faz com que todo o script falhar muito mal.

Qualquer conselho é apreciado, no entanto eu preferiria não usar grandes plugins para esta tarefa aparentemente simples.

Foi útil?

Solução

Quando eu corri o código fornecido, eu fui pego em um loop infinito. No final do loop faz, você tem

current_value = parseInt(numb);

mas o valor de dormentes só é definido no início da função, por isso vai durar para sempre. Se você mudar isso para

current_value = parseInt($(id).html());

, em seguida, ele funciona bem. Exceto que ele parece acontecer instantaneamente.

Eu cortei-se um método para alcançar a animação usando o tempo limite que parece funcionar razoavelmente bem, mas como eu ainda sou bastante novo para JavaScript Eu não sei se há uma abordagem mais eficiente ou não. Apenas ajustar o segundo param passado para setTimeout para obter a velocidade desejada. E se você quiser alterar o valor de incremento / decréscimo, basta alterar a desaceleração da 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);
    }
}

Outras dicas

O que você está fazendo aqui é atualizar o DOM muitas vezes em rápida sucessão. Como resultado, o navegador irá esperar até que tenha feito todas as suas alterações, e só então irá re-desenhar a página. Assim, você não vai conseguir ver qualquer mudança visual até que o número vai todo o caminho até 4000.

Sim, você precisa usar um setTimeout ou setInterval / clearInterval. Ou, para maior clareza do código, você poderia usar o jQuery "espera" plug-in :

// (code to get new value goes here)

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

Em vez de html(), eu tenho text() usado, uma vez que parece que você não precisa alterar qualquer estrutura HTML.

Eu gosto de abordagem de espinho com setTimeout, mas eu gostaria de condensá-lo para baixo para 2 funções e iniciá-lo após o carregamento da janela para garantir a página foi carregada antes de atualizar o contador:

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);
    }
}

O caso base não está satisfeita no caso $ class.html () começa com um valor maior do que o targetVal no caso de 'Adicionar' ou inferior ao targetVal no outro caso. Você teria que garantir que isso não aconteça antes de fazer a chamada de função.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top