jQuery Blues: 7. Efectos básicos

En esta entrada de la serie dedicada a jQuery veremos cómo realizar efectos sencillos y seguiremos trabajando con el selector contextual this.

klimt

archivado en: JavaScript / 25 noviembre, 2012 / taller:

Seguimos con jQuery. En esta entrada veremos algunos efectos muy chulos que se pueden conseguir de forma muy sencilla y, de paso, trabajaremos un poco más con this.

Hay tres efectos básicos en jQuery:

  • .hide(): oculta un elemento
  • .show(): muestra un elemento
  • .toggle(): muestra u oculta un elemento según se haya seleccionado antes

En los tres casos, la sintaxis es similar, se añaden tras un punto tras el selector:

  • jQuery('selector').hide();

Además, en el paréntesis, se puede indicar si el efecto debe ser inmediato, dejándolo en blanco, lento (slow) o rápido (fast), lo cual también se puede hacer especificando los milisegundos (200 es lento, 600 rápido). Si se indica con una cadena de texto —slow o fast— hay que usar comillas, si es en milisegundos, no. Por ejemplo, vamos a recuperar el menú que hicimos hace algunas entradas, pero con algunos pequeños cambios: quitamos los identificadores de cada lista y las subopciones las ponemos en una lista que ocupa el segundo <li> de la lista principal.

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>
  • efectos
  • </title>
  • <style type="text/css">
  • #menu {
  • overflow: hidden;
  • }
  • #menu ul{
  • float: left;
  • list-style-type:none;
  • list-style-type:none;
  • padding:0em;
  • width:8em;
  • }
  • .listas_menu {
  • border-right: 1px solid #900;
  • border-left: 1px solid #f33;
  • background-color:#c00;
  • font-weight:bold;
  • color:#fff;
  • }
  • .listas_menu li {
  • border-top: 1px solid #f33;
  • border-bottom: 1px solid #900;
  • padding:0.3em;
  • cursor: pointer;
  • }
  • </style>
  • </head>
  • <body>
  • <nav id="menu">
  • <ul class="listas_menu">
  • <li>Opción 1</li>
  • <ul class="subopciones">
  • <li>Subopción 1.1</li>
  • <li>Subopción 1.2</li>
  • <li>Subopción 1.3</li>
  • </ul>
  • </ul>
  • <ul class="listas_menu">
  • <li>Opción 2</li>
  • <ul class="subopciones">
  • <li>Subopción 2.1</li>
  • <li>Subopción 2.2</li>
  • <li>Subopción 2.3</li>
  • </ul>
  • </ul>
  • <ul class="listas_menu">
  • <li>Opción 3</li>
  • <ul class="subopciones">
  • <li>Subopción 3.1</li>
  • <li>Subopción 3.2</li>
  • <li>Subopción 3.3</li>
  • </ul>
  • </ul>
  • </nav>
  • </body>
  • </html>

El resultado debería quedar similar a esta imagen:

[singlepic id=24 w=405 h=148 float=center]

Ahora ya solo nos falta añadir algo de jQuery. Lo primero, mediante el método hide() y sin indicar ningún valor para que sea instantáneo al cargar la página (on document ready), ocultamos la segunda lista:

  • <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  • <script type="text/javascript">
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos la segunda lista
  • jQuery(".subopciones").hide();
  • });
  • </script>

Y ahora podemos decirle que al pasar el cursor (hover) se despliegue la respectiva lista mediante this.

  • <script type="text/javascript">
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos la segunda lista
  • jQuery(".subopciones").hide();
  • // al pasar el cursor en li de la primera lista, se despliega la segunda 
  • jQuery(".listas_menu", this).hover(
  • function(){
  • jQuery(".subopciones", this).show(400);
  • },
  • function(){
  • jQuery(".subopciones", this).hide("fast");
  • }
  • );
  • });
  • </script>

Si no hubiéramos acotado mediante this, al pasar el cursor sobre la primera lista habría mostrado todas, pero con this solo muestra «esta», la sublista que se encuentra dentro de la que ha desencadenado la acción.

Toggle()

Toggle() funciona de manera algo distinta. Si en el caso anterior en vez de usar un hover() hubiéramos aplicado un click(), el menú sería un desastre. Se desplegaría una vez pulsado, pero luego ya se quedaría visible para toda la eternidad. Bueno, se podría hacer algún apaño con una estructura condicional que evaluara si el nodo objetivo, el target de la acción, está desplegado o no, pero sería una ñapa, sobre todo si disponemos del método toggle().

Este método evalúa si un selector ya ha sido pulsado o no y, en función de eso, hace una cosa u otra. Si no se le pasa ningún parámetro, directamente oculta o muestra el contenido.

  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos la segunda lista
  • jQuery(".subopciones").hide();
  • // al pinchar la primera lista, se despliega la segunda
  • jQuery(".listas_menu", this).click(function () {
  • jQuery(".subopciones", this).toggle();
  • });
  • });

Pero si se le indica la velocidad, se comporta como las animaciones anteriores.

  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos la segunda lista
  • jQuery(".subopciones").hide();
  • // al pinchar la primera lista, se despliega la segunda
  • jQuery(".listas_menu", this).click(function () {
  • jQuery(".subopciones", this).toggle("slow");
  • });
  • });

Slides y fades

Otro grupo de efectos sencillos son los slides, es decir, que las cosas aparezcan o desaparezcan recorriendo un pequeño espacio. Son tres métodos:

  • .slideUp(): oculta el elemento
  • .slideDown(): lo muestra
  • .slideToggle(): un toggle.

Y la sintaxis es muy parecida a la anterior, se declara el método ligado al selector tras un punto y en el paréntesis se indica un valor en milisegundos o con las cadenas de texto slow y fast.

  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos la segunda lista
  • jQuery(".subopciones").hide();
  • // al pasar el cursor en li de la primera lista, se despliega la segunda
  • jQuery(".listas_menu", this).hover(
  • function(){
  • jQuery(".subopciones", this).slideDown("slow");
  • },
  • function(){
  • jQuery(".subopciones", this).slideUp("slow");
  • }
  • );
  • });

El grupo de los fades (fundidos o desvanecimientos) funciona exactamente igual. Son cuatro:

Y la sintaxis es la de antes, menos en el caso de fadeTo, que necesita un segundo parámetro, del 0 al 1, para indicar hasta dónde debe dejarse la opacidad:

  • .fadeTo( 200, 0.5)

Callback de funciones

Si los efectos que se desencadenan son complejos, y en la siguiente entrada veremos animaciones más sofisticadas, es muy importante priorizar los efectos, es decir, indicar que hasta que no concluya uno no empiece otro. Para que se entienda este concepto vamos a hacer una especie de buscaminas, el juego que tienes que pulsar casillas y si hay una mina explota.

Lo primero es hacer una tabla en cuyas celdas habrá dos span, uno con una interrogación y otro con la mina: un 0 si no hay y un 1 si esconde la mina. Además, añadiremos un párrafo con la explosión. (Es recomendable ir haciendo el ejercicio a media que se va leyendo).

Algo así:

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>
  • efectos
  • </title>
  • <style type="text/css">
  • #tabla {
  • border: 1px solid #000;
  • }
  • #tabla td {
  • border: 1px solid #999;
  • min-width:3em;
  • min-height:3em;
  • }
  • #explosion {
  • font-size: 4em;
  • color:#900;
  • }
  • .interrogacion {
  • cursor:pointer;
  • }
  • </style>
  • </head>
  • <body>
  • <table id="tabla">
  • <tr>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • </tr>
  • <tr>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="con_mina">1</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • </tr>
  • <tr>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • <td><span class="interrogacion">?</span><span class="sin_mina">0</span></td>
  • </tr>
  • </table>
  • <p id="explosion">BOOOOM!</p>
  • </body>
  • </html>

Que quedaría de esta manera en pantalla:

[singlepic id=25 w=324 h=219 float=center]

El código jQuery que necesitamos para el juego es sencillo. Basta con ocultar las minas y la explosión al principio y luego ir mostrando lo que hay en cada celda al hacer click en esa, en this. Además, al pulsar en la mina, debe aparecer la explosión. Algo así:

  • <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  • <script type="text/javascript">
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // nada más cargar, ocultamos el contenido de cada celda y la explosión
  • jQuery(".sin_mina, .con_mina, #explosion" ).hide();
  • // al pulsar en la celda, ocultamos la interrogación y mostramos su contenido oculto
  • jQuery("#tabla td", this).click (function () {
  • jQuery(".interrogacion", this).fadeOut("slow");
  • jQuery(".sin_mina", this).fadeIn("fast");
  • jQuery(".con_mina", this).fadeIn("fast");
  • });
  • // al pulsar la mina, mostramos la explosión
  • jQuery(".con_mina").click (function () {
  • jQuery("#explosion").slideDown("slow");
  • });
  • });
  • </script>

Sin embargo, al hacerlo así, surgen dos problemas: uno, como la interrogación desaparece más lenta que la mina, durante un instante conviven en pantalla, lo cual fastidia la animación; y dos, la explosión solo se muestra al re-pulsar en la mina.

[singlepic id=26 w=225 h=90 float=center]

Y es ahora cuando viene en nuestro auxilio la posibilidad de hacer un «callback de funciones».  🙂

Ya sabemos qué es una función, aunque sea de forma intuitiva, porque llevamos varias entradas trabajando con ellas. Son un conjunto de instrucciones indicadas entre llaves:

  • soy_una_funcion () {
  • instrucción 1;
  • instrucción 2;
  • }

Las funciones se pueden llamar en cualquier parte del código. Por ejemplo, mediante la instrucción return esta función devuelve la cadena de texto "soy una función":

  • soy_una_funcion () {
  • return "soy una función";
  • }

Así, si en una página escribiéramos

  • soy_una_funcion();

Obtendríamos el texto mencionado. Además, en el paréntesis que sigue al nombre de la función se pueden indicar parámetros que afectan al conjunto de instrucciones. Estos parámetros se denominan argumentos. 

Por razones que no vienen al caso ahora, a veces las funciones reciben el nombre de métodos (cuando forman parte de una clase en la programación orientada a objetos). Es decir, cuando escribimos:

  • jQuery ("selector").css("display", "block")

es como si estuviéramos llamando a la «función» css pasándonle dos argumentos: la propiedad a modificar y el nuevo valor que debe tener. Al igual que:

  • jQuery(".interrogacion", this).fadeOut("slow");

Equivaldría a llamar a la función fadeOut pasándole como argumento "slow".

Vale, volvamos ahora con jQuery y el buscaminas. Resolvamos primero las casillas sin mina.

En muchos métodos, como los efectos que hemos visto, jQuery permite incluir una función como argumento del método. Es lo que se denomina funciones callback (de llamada).

En los efectos se indica como último argumento y sirve para decirle a jQuery que cuando termine el primer efecto, comience los que se indican en la función callback.

  • jQuery("#tabla td", this).click (function () {
  • jQuery(".interrogacion", this).fadeOut("slow", function(){
  • jQuery(".sin_mina", this).fadeIn("fast"); 
  • });
  • });

Así, en el caso anterior, en teoría primero hace un fadeOut sobre  «este» (this) span de la clase .interrogacion y luego llama a una función en la que se hace un fadeIn sobre el span .sinmina. Pero solo en teoría, ya que esto nos plantea un nuevo problema. Como el selector de la segunda función es distinto al que ha desencadenado la acción, no podemos usar this tal cual, porque no sabe ya cuál es el this original.

Para solucionar esto podemos recoger el this original en una variable, para que no se pierda con el correr de funciones, y luego en vez de this, definiremos como contexto esa variable. (Si no sabes qué es es una variable, por favor, mira esta entrada y la siguiente).

  • jQuery("#tabla td", this).click (function () {
  • var variable_recoge_this = jQuery(this);
  • jQuery(".interrogacion", this).fadeOut("slow", function(){
  • jQuery(".sin_mina", variable_recoge_this).fadeIn("fast");
  • });
  • });

Como vemos, al igual que sucede con JavaScript, las variables en jQuery se declaran precediéndolas por la palabra reservada var y luego ya se pueden usar tal cual (sin precederlas del símbolo $, como ocurre en PHP). Para ponerle nombres a las variables, lo normal en jQuery es usar el llamado sistema CamelCase (mayúsculas de camello), en el que se pone en mayúscula la primera letra de cada palabra:

  • VariableRecogeThis

Sin embargo, a mí me gusta más emplear el guion bajo. Tanto da un sistema como otro, basta con no emplear caracteres de html atípicos, como acentos o eñes.

Vale, ya nos funciona de forma correcta el buscaminas cuando no hay minas. Veamos ahora cómo resolver qué sucede cuando hay una mina. ¿Se te ocurre cómo solucionarlo antes de seguir leyendo?

Sí, la solución es tan sencilla como incluir como argumento en el método que destapa la mina una función que descubra la explosión.

  • jQuery("#tabla td", this).click (function () {
  • var recoge_this = jQuery(this);
  • jQuery(".interrogacion", this).fadeOut("slow", function(){
  • jQuery(".sin_mina", recoge_this).fadeIn("fast");
  • jQuery(".con_mina", recoge_this).fadeIn("fast", function() {
  • jQuery("#explosion").slideDown("slow");
  • });
  • });
  • });

Y ya nos quedaría un buscaminas formidable.

Práctica

Pues para terminar esta entrada, una práctica  ;-).

Hay que hacer una página con texto y unas imágenes y que al pasar el cursor por alguna  imagen, aparezca con un efecto un texto que la describa. Algo así:

[singlepic id=27 w=600 h=263 float=center]

|| Tags:

valoración de los lectores sobre jQuery Blues: 7. Efectos básicos

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4 sobre 5 (11 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.