loopDelayed – modifique um elemento gradualmente

Tenho usado freqüentemente scripts como fat.js e blendtrans.js para criar efeitos de fade em elementos HTML, aqueles que se excuta por um determinado espaço de tempo, permitindo ao usuário ver o elemento mudar de cor ou sumir/aparecer lentamente.

Bem, por curiosidade, fui ver como a coisa era feita nos dois scripts citados acima e me assustei com a simplicidade. É um simples loop que ao invés de executar comandos diretamente usa a função setTimeout, incrementando o timeout a cada volta. Mas os dois scripts tem funções dedicadas a determinada propriedade do elemento: o fat.js muda a cor e o blendtrans.js, a opacidade. Fiquei pensando em uma função polivalente que permitisse fazer mudanças em outras propriedades de um elemento durante um período de tempo e dessas elocubrações nasceu a função loopDelayed.

Antes de mostrar a função, vamos entender o que ela faz. Enviaremos para ela os seguintes parâmetros:

  1. o ID do elemento a ser modificado
  2. o valor inicial para o loop
  3. o valor final para o loop
  4. intervalo em milisegundos
  5. o nome da função que irá modificar o elemento

Portanto se fizermos uma chamada assim:

loopDelayed("meu_elemento", 0, 4, 5000, "minha_func");

Isso significa que a função loopDelayed irá executar 5 chamadas à função minha_func com 5 segundos de intervalo entre as chamadas e enviando como parâmetro o elemento (como objeto DOM) e o número equivalente à volta do loop solicitado:

  1. minha_func([Object], 0); // imediatamente
  2. minha_func([Object], 1); // 5 seg. depois
  3. minha_func([Object], 2); // 10 seg. depois
  4. minha_func([Object], 3); // 15 seg. depois
  5. minha_func([Object], 4); // 20 seg. depois

Se houvesse mais do que 5 parâmetros, os excedentes (6º, 7º, 8º, etc.) seriam enviados à minha_func, como os parâmetros 3, 4, 5, etc.

Entendida a idéia, vamos à função:

function loopDelayed(id, ini, end, delay, func) {
_looping = (typeof(id) == "object" ? id : document.getElementById(id)) || null;
var args = loopDelayed.arguments, interval = 0, params = [];

  if(args.length < 5 || ini == end || !_looping) return;

  if(args.length > 5)
    for(var i = 5; i < args.length; i++)
      if(/number|boolean|null|string/i.test(typeof(args[i])))
        params.push(typeof(args[i]) == "string" ? "'"+args[i]+"'" : args[i]);
params = params.length ? ", "+params.join(", ") : "";

  if(ini < end) {
    for(var i = ini; i <= end; i++) {
    setTimeout(func+"(_looping , "+i+params+");", interval);
    interval += delay;
    }
  } else {
    for(var i = ini; i >= end; i = i - 1) {
    setTimeout(func+"(_looping, "+i+params+");", interval);
    interval += delay;
    }
  }
}

Bem, não se trata exatamente de "uma função polivalente que muda várias propriedades", mas de uma função que aplica uma dada função a um elemento um determinado número de vezes, com um determinado espaço de tempo entre as chamadas e isso permite criar modificações graduais em qualquer propriedade de um elemento HTML, durante um certo período de tempo.

Aí há ainda uma pulga atrás da orelha: se iniciamos o loop em 0 e vamos até 3, comm 500 milisegundos de delay, a última chamada deveria acontecer exatamente 1500 milisegundos após o disparo, mas sempre demora um pouco mais… mas nada que inviabilize o uso. Vou acabar descobrindo porquê…

Veja aqui uma página com exemplos de como criar funções para interagir com a função loopDelayed.

Uma ideia sobre “loopDelayed – modifique um elemento gradualmente

  1. Bixo, precisei disso hoje uaehaehuae, pena que não li antes.

    Dá uma lida no método call() e apply() lá no MDC. Assim não precisará passar o nome da função via string só por causa de ter que enviar parametros pra ela.

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>