sábado, 21 de mayo de 2011

Galería de imágenes usando jQuery

Continuando con el artículo anterior, vamos a ver cómo hacer una sencilla galería de imágenes estáticas. Este ejemplo y el código del mismo, está basado en How to Create your own jQuery Slider Plugin, aunque le he modificado algunas cosas para mejorar su reutilización, manteniendo la misma idea y sin grandes cambios.

La técnica usada es una de las más comunes, y se puede adaptar a muchas otras cosas. Tenemos una lista de imágenes, inicialmente ocultas, que se irán mostrando de a una a la vez, usando algo de JavaScript. Agregándole un efecto en la transición del cambio de imagen, es de lo más trivial gracias a jQuery, logrando un resultado mucho más cuidado.

Vamos por partes.

Primer paso: el HTML

<div class="slideshow">
        <h3><a href="#">Título</a></h3>
        <ul>
                <li><img src="..." /></li> 
                <li><img src="..." /></li> 
                <li><img src="..." /></li> 
        </ul>
        <div class="counter"></div>
</div>

El <div> con clase "slideshow" será el contenedor. Se usará para inicializar el plugin de jQuery y para brindarle estilos al componente. Dentro hay un título, una lista de elementos con UL-LI, y un contenedor para mostrar el número de página actual y el número total. Es interesante el uso de una lista UL, porque semánticamente expresa mejor su intención, que por ejemplo si hubiésemos usado DIV, SPAN, TABLE, u otro elemento. Las listas también las podemos encontrar adecuadas para representar pestañas/tabs, etiquetas, menúes, etc., al menos hasta usar HTML5, que nos trae nuevas etiquetas más específicas, como NAV.

Segundo paso: el CSS

<style>
.slideshow { background:#FFF; width:500px; border:1px #000 solid; margin:20px auto; padding:15px;}
.slideshow ul { width:500px; height:auto; min-height: 335px; overflow: hidden; position:relative; padding:0; margin:0;}
.slideshow li { position:absolute; top:0px; left:0px; display:none; list-style:none;}
.slideshow li img { width: 100% }
.slideshow li:first-child {display:block;}
.slideshow .counter {text-align:right; width:100%;}
</style>

Los 500px en las lineas 3 y 5 determinan el ancho de la galería. Los 335px en la linea 5 determinan la altura. En la linea 7, se hacen invisibles todos los LI con display:none, y se les quita toda la decoración por defecto (el círculo o botón que prefija a cada elemento de una lista). Después, en la linea 11 se hace visible solo al primer elemento de la lista.
El UL tiene position:relative, y los LI tienen position:absolute. Como el contenedor de los LI (el UL) tiene posicionamiento, las coordenadas de los LI toman como origen de las coordenadas a su padre, y se posicionan todos en (0px, 0px), lo que hace que todos los elementos queden en el mismo lugar. Podemos pensar que están como "apilados", unos encima de otros (pero no tienen distinto z-index, realmente están todos al mismo nivel de stack).

Tercer y último paso: el JavaScript

(function($){
        $.fn.slideshow = function(interval) {
                var slides;
                var cnt;
                var amount;
                var i;
                function run() {
                        // hiding previous image and showing next
                        $(slides[i]).fadeOut(1000);
                        i++;
                        if (i >= amount) i = 0;
                        $(slides[i]).fadeIn(1000);
                        // updating counter
                        cnt.text(i+1+' / '+amount);
                        // loop
                        setTimeout(run, interval);
                }
                slides = $(this).find('ul').children();
                cnt = $(this).find('.counter');
                amount = slides.length;
                i=0;
                // updating counter
                cnt.text(i+1 + ' / ' + amount);
                setTimeout(run, interval);
        };
})(jQuery);
$(function(){
        $('.slideshow').slideshow(5000);
});

Aquí voy a tener que deternerme un poco más. Entre las lineas 1 y 51 se crea un plugin de jQuery. Este fragmento deberíamos guardarlo en un archivo aparte como slider-jquery-plugin.js para vincularlo a la página.
Las líneas 54 a 56 es una forma típica de realizar inicializaciones con jQuery, es decir, de ejecutar algo una vez que la página está cargada y la DOM está liberada para recibir modificaciones. La expresión $('.slideshow') de jQuery busca a los elementos que tengan el class 'slideshow', y les aplica el plugin slideshow(), El parámetro que se pasa es el tiempo en milisegundos que queremos de demora entre una imagen y la siguiente, en este caso de 5 segundos.
Luego, entre las lineas 35 y 47 se hace la incialización del plugin. No voy a detenerme aquí, pero basta decir que recupera a los elementos hijos del UL (los LI) y los guarda en un arreglo llamado 'slides', y en la linea 47 registra un timer que llamará al método run() del plugin en X tiempo (que fue recibido por parámetro).
El método run(), definido entre las lineas 13 y 33, es donde sucede lo interesante. Primero hace un efecto fadeOut() ("desaparecer") sobre el item actual, avanza al siguiente item, y hace un efecto fadeIn() ("aparecer") sobre el siguiente elemento. Si se llega al último elemento, se vuelve a comenzar con el primero. Se actualiza el contador de página/imagen actual, y se vuelve a registrar un timer para volver a llamar a run() en otro X tiempo.
Lo interesante de esto, es que se aprovecha de una característica de los efectos especiales (FXs) de jQuery, que son implementados como animaciones. Estas animaciones, cuando inicializan, en realidad estamos pidiendo que comiencen, y durarán un tiempo predefinido (normalmente 200 milisegundos, que se puede cambiar pasando un parámetro al efecto). Entonces, al solicitar la desaparición del elemento actual, y la aparición del elemento siguiente, y al animarse ambos a la vez, para nuestros ojos se produce un efecto de fusión (o morph) de una imagen en otra, que es solo un efecto visual. Como ven, era más largo explicarlo que hacerlo :D
Al combinar todo, recuerden que deben incluir la libería JavaScript de jQuery. Una forma de hacerlo es cargarla desde el CDN (Content Delivery Network) de Google, donde está a disposición de los desarrolladores web muchas librerías JS de uso habitual. Por ejemplo, pueden hacerlo así:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
Les dejo una versión completa para descargar y probar localmente. A continuación tienen el ejemplo terminado. No olviden hacer sus comentarios y sugerencias.

1 comentario :

Omar Galaviz dijo...

Como es que slide no es declarado como un array?.. bueno voy a probarlo, lo que realmente quiero es implementar la logica pero con eventos $().click(), para boton de next y back..

Saludos. gracias por la traduccion y la explicación

Omar Galaviz