Cola de efectos personal (no predeterminada) en jQuery

  • Por
Vamos a mostrar cómo trabajar con otras colas de efectos distintas que la cola de efectos predeterminada.
En los anteriores capítulos del Manual de jQuery hemos aprendido que cada elemento de la página tiene incorporada una cola de efectos predeterminada que funciona automáticamente, con sólo invocar las funciones de efectos que deseemos. Esta cola de efectos por defecto, será suficiente para realizar la mayoría de las aplicaciones web que podamos imaginarnos, no obstante, también tenemos la posibilidad de generar nuestras propias colas de efectos, aunque en este caso tendremos que gestionarlas de una manera un poco diferente.

La mayoría de los métodos para trabajar con colas de efectos tienen un parámetro que es una cadena con el nombre la la cola de efectos que queremos alterar. Este parámetro resulta opcional cuando queremos trabajar con la cola de efectos predeterminada, por lo que, en los casos vistos hasta ahora y como siempre trabajábamos con la cola de efectos predeterminada, nunca necesitábamos utilizarlo. Básicamente aprenderemos en este artículo la posibilidad de especificar ese parámetro y gestionar varias colas, que podrían ejecutarse de manera simultánea.

Nota: la cola de efectos predeterminada de jQuery se llama "fx", por lo que nuestras colas de efectos personales deberán tener otros nombres.

Ejemplo con una cola de efectos no predeterminada

Para ilustrar el modo de trabajo con una cola de efectos distinta de la predeterminada vamos a realizar un ejemplo en el que tendremos dos colas de efectos distintas. Una será la cola predeterminada, que ya sabemos manejar, y otra será una cola de efectos personal.

Si lo deseas, antes de ponernos manos a la obra, puedes acceder al ejemplo en marcha.

Nota: Hemos decidido trabajar con dos colas de efectos distintas para que se vea que se pueden poner en marcha y realizar su ejecución al mismo tiempo.

Primero podemos ver la función que implementará la cola de efectos predeterminada, que ya sabemos cómo funciona:

function ocultaMuestra(){
   capa = $("#micapa");
   capa.fadeTo(500, 0.3);
   capa.fadeTo(1200, 1);
   capa.animate({
      "left": "350px"
   },1200);
   capa.animate({
      "left": "100px"
   },1000, ocultaMuestra);
}

Como vemos, estamos definiendo una función llamada ocultaMuestra() y en ella estamos lanzando varias invocaciones a funciones de efectos de jQuery, que se cargan siempre en la cola de efectos predeterminada. Al final de esta función, en la última llamada a animate(), realizamos un callback para invocar de nuevo a ocultaMuestra() y así generar un bucle infinito de efectos.

Ahora podemos ver la función que realizará una cola de efectos distinta de la predeterminada.

function cambiarColores(){
   capa = $("#micapa");
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#339"
      });
      setTimeout("capa.dequeue('micola')", 1000);
   });
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#933"
      });
      setTimeout("capa.dequeue('micola')", 1000);
   });
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#393"
      });
      setTimeout("cambiarColores()", 1000);
   });
   capa.dequeue("micola");
}

La función cambiarColores(), que acabamos de ver, encola varias funciones y lo hace en una cola de efectos llamada "micola".

Como todas las funciones que se meten en "micola" no son de efectos (porque si no, se encolarían en la cola predeterminada), tenemos que encolarlas con el método queue(), indicando la cola con la que estamos trabajando y la función a encolar en ella.

Antes de acabar cualquier función de las que metemos en "micola", tenemos que llamar a dequeue("micola") indicando como parámetro la cola en la que queremos progresar al siguiente elemento encolado. Ese dequeue() se realiza además con un setTimeout() para retrasar un poco la ejecución de las siguientes funciones.

Al final de código de la función cambiarColores() hay un dequeue("micola") que sería necesario para que, una vez definida la cola, se comience la ejecución con la primera función de la misma.

Otra posibilidad para la función cambiarColores() pero un poco más avanzada y que será útil de mostrar, ya que en el artículo anterior aprendimos a trabajar con el método delay(), sería la siguiente:

function cambiarColores(){
   capa = $("#micapa");
   capa.delay(1000, "micola");
   capa.queue("micola", function(sig){
      $(this).css({
         "background-color": "#339"
      });
      sig()
   });
   capa.delay(1000, "micola");
   capa.queue("micola", function(sig){
      $(this).css({
         "background-color": "#933"
         
      });
      sig();
   });
   capa.delay(1000, "micola");
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#393"
      });
      cambiarColores();
   });
   capa.dequeue("micola");
}

La diferencia es que hemos modificado los setTimeout() por llamadas al método delay(1000, "micola"), que produce un retardo de 1 segundo antes de pasar al siguiente elemento de la cola "micola". Además, dentro de las funciones que insertamos con queue(), llamamos a la siguiente fase de la cola a través del parámetro "sig", que tiene una referencia a la siguiente función de la cola

Podemos ver este ejemplo con su código completo:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Otra cola de efectos</title>
<script src="../jquery-1.4.2.min.js" type="text/javascript"></script>   
<style type="text/css">
body{
   font-size: 0.75em;
   font-family: tahoma, verdana, sans-serif;
}
#mensaje{
   margin: 20px 5px;
}
#micapa{
   left: 100px;
   top: 150px;
   position: absolute;
   width: 50px;
   height: 50px;
   background-color: #3d3;
}
</style>
<script languague="javascript">
function muestraRestantesCola(){
   var funcionesEnCola = $("#micapa").queue("micola").length;
   var funcionesEnColaPredeterminada = $("#micapa").queue().length;
   //console.log("Cola 'micola':", $("#micapa").queue("micola"));
   
   var textoMostrar = "Hay " + funcionesEnCola + " funciones de efectos en la cola 'micola'";
   textoMostrar += "<br>Hay " + funcionesEnColaPredeterminada + " funciones de efectos en la cola por defecto";
   $("#mensaje").html(textoMostrar);
}

function cambiarColores(){
   capa = $("#micapa");
   capa.delay(1000, "micola");
   capa.queue("micola", function(sig){
      $(this).css({
         "background-color": "#339"
      });
      sig()
   });
   capa.delay(1000, "micola");
   capa.queue("micola", function(sig){
      $(this).css({
         "background-color": "#933"
         
      });
      sig();
   });
   capa.delay(1000, "micola");
   capa.queue("micola", function(sig){
      $(this).css({
         "background-color": "#393"
      });
      cambiarColores();
   });
   capa.dequeue("micola");
}

/*
POSIBILIDAD PARA HACER ESTA MISMA FUNCIÓN PERO CON SETTIMEOUT EN VEZ DE DELAY
function cambiarColores(){
   capa = $("#micapa");
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#339"
      });
      setTimeout("capa.dequeue('micola')", 1000);
   });
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#933"
      });
      setTimeout("capa.dequeue('micola')", 1000);
   });
   capa.queue("micola", function(){
      $(this).css({
         "background-color": "#393"
      });
      setTimeout("cambiarColores()", 1000);
   });
   capa.dequeue("micola");
}
*/

function ocultaMuestra(){
   capa = $("#micapa");
   capa.fadeTo(500, 0.3);
   capa.fadeTo(1200, 1);
   capa.animate({
      "left": "350px"
   },1200);
   capa.animate({
      "left": "100px"
   },1000, ocultaMuestra);
}

$(document).ready(function(){
   cambiarColores();
   ocultaMuestra();
   $("#botontamanocola").click(function(){
      muestraRestantesCola();
   });
});
</script>

</head>
<body>
   <button id="botontamanocola">Muestra el número de funciones en cola ahora mismo</button>
   <div id="mensaje">
   </div>
<div id="micapa"></div>
</body>
</html>

Para acabar, colocamos el enlace al ejemplo en marcha.

Con esto hemos terminado todo lo que queríamos explicar sobre colas de funciones para realizar todo tipo de efectos complejos en jQuery. Esperamos que se haya podido entender y a partir de aquí el lector sea capaz de aplicar los conocimientos para implementar efectos especiales en scrips complejos con jQuery.

En el próximo artículo aplicaremos los conocimientos sobre colas de efectos para mejorar el plugin del navegador desplegable en jQuery para aplicar efectos especiales.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Alexis Advance

12/11/2010
Algo muy importante
Se les escapa algo muy importante: ¿cómo puedo agregar en la cola de efectos personal una función que NO es de efectos? Al no ser de efectos, se debería prescindir del método queue(), entonces, sin él, ¿cómo puedo especificar que quiero agregar esa función a la cola de efectos personal?

Ojalá me puedan responder. ¡Saludos!

Alexis Advance

12/11/2010
Acerca del comentario anterior
Soy quien escribió el comentario anterior. Quiero corregirla porque pregunté mal. En lugar de ser:

«¿cómo puedo agregar en la cola de efectos personal una función que NO es de efectos?»

quise preguntar:

«¿cómo puedo agregar en la cola de efectos personal una función que SÍ es de efectos?»

En el artículo, a la cola personal solamente le agregas funciones que no son de efectos, por ejemplo: $(this).css({ "background-color": "#339" });. Pues me gustaría saber cómo agregar funciones que sí son de efectos a la cola personal. Intenté lo siguiente, pero no funcionó:

capa.queue("micola", function(){
capa.animate({
"left": "350px"
},1200);
capa.animate({
"left": "100px"
},1000);
}

En el artículo mencionas que «la mayoría de los métodos para trabajar con colas de efectos tienen un parámetro que es una cadena con el nombre la la cola de efectos que queremos alterar», pero no explican nada de eso más adelante. De acuerdo a lo que pude comprender del texto, intenté lo que pondré a continuación, pero tampoco me funcionó:

capa.animate("micola"{ // En esta línea le paso como primer parámetro el nombre de la cola personal
"left": "350px"
},1200);