Crear un slideshow con jquery

Crear un slideshow de contenidos puede quitarnos un poco de tiempo. En este ejemplo vamos a utilizar jquery para reducir un poco el trabajo. Gracias a las facilidades que ofrece jquery para la manipulación del DOM, el código resultante puede ser bastante reducido en comparación de una implementación sin utilizar un framework como jquery.

Recientemente he estado trabajando en un módulo para Drupal para crear un style para views que me permita mostrar diferentes contenidos con botones de "siguiente" y "anterior" utilizando javascript para ocultar y mostrar y esconder los contenidos correspondientes. Primero decidí crear el código javascript necesario para realizar la tarea y de eso se trata este ejemplo. Ok manos a la obra.

Supongamos que tenemos el siguiente código HTML:

<html>
<head>
   <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
   <title>Jquery Testing</title>
   <script src="jquery.js" type="text/javascript" language="javascript" charset="utf-8" /></script>
   <script src="effects.js" type="text/javascript" language="javascript" charset="utf-8" /></script>
</head>
<body> 
<div id="buttons">
 
</div>
<div id="items">
    <p> Contenido 1 </p>
    <p> Contenido 2 </p>
    <p> Contenido 3 </p>
</div>
</body>
</html>

Ahora lo primero que tenemos que hacer es esconder los dos últimos <p> y colocar una bandera en el primera para saber que esa etiqueta está activo. Para eso utilizamos el siguiente código javascript

Archivo effects.js

$(document).ready(function () {
    //Set active first element and hide others
    $("#items p:first").addClass("active");
    $("#items p:not(:first)").hide();
});

Después debemos crear una función que nos permite ir por cada tag de parráfo y mostrarlo, además de esconder los otros. Para eso vamos a crear un objeto llamado Rotator que va a tener dos funciones. La primera función es "changeSlide" que permite cambiar de contenido.

var autostart = 1;
//Guarda el id del timer en caso de querer detenerlo con la función clearTimeout()
var timeOut = null;
//Inicializamos el objeto
var Rotator = {};
//Tiempo en milisegundos entre cada elemento
var timeSeconds = 2000;
//Decide si mostrar los botones o no
var buttons = 1;
 
/**
 * Change the content to the next o prev slide
 *
 * @param integer way
 *   Choose if the buttos is next or prev
 * @param integer event 
 *   event is 1 when changeSlide is called it from button next or prev.     
 * @return void
 */
Rotator.changeSlide = function (way, event) {
    var $active = $("#items p.active");
    $active.removeClass("active");
    $active.hide("slow");
    switch (way) {
        case -1:
        if ($active.prev().length) {
            $active.prev().addClass("active");
            $active.prev().show("slow");
        }else {       
            $("#items p:last").addClass("active");
            $("#items p:last").show("slow");
        }
        break;        
        case 1:
        if ($active.next().length) {
            $active.next().addClass("active");
            $active.next().show("slow");
        }else {       
            $("#items p:first").addClass("active");
            $("#items p:first").show("slow");
        }
        break;
    }
 
    if (autostart) {
        //Check if was a click event
        if (event == 1) {
            clearTimeout(timeOut);
        }        
        timeOut = setTimeout('Rotator.changeSlide(1, 0)', timeSeconds);
    }
};

Como pueden observar esta función recibe 2 parámetros:

  • way: permite verificar si se mueve un paso adelante o atrás
  • event: permite verificar si el llamado de la función vino de un evento de clic de un botón o es parte del flujo (para esto la variable autostart). En caso de que el parámetro autostart esté activo y también se haya dado clic en algún botón es mejor reiniciar el timer de la función porque puede crear conflictos (clearTimeout(timeOut)

En esta función se puede observar claramente como obtenemos el contenido que se está visualizando mediante var $active = $("#items p.active");. Se procede a eliminar dicha clase y a verificar si se quiere el siguiente elemento o el anterior.

La siguiente función se utiliza para agregar los botones para manejar el contenido y agregar también los eventos de clic a estos botones.

/**
 * Make html for buttons and bind click events
 *
 * @return void
 */
Rotator.makeButtons = function() {
    var buttonStopText = (autostart == 1) ? "Stop" : "Play";   
    //Load buttons
    $("#buttons").html('');
    $("#buttons").append('<a href="#" class="button-prev">Prev</a> - ');
    $("#buttons").append('<a href="#" class="button-stop">' + buttonStopText + '</a> - ');
    $("#buttons").append('<a href="#" class="button-next">Next</a>');    
 
    //Events
    $("#buttons a.button-prev").bind("click", function (event) {
        Rotator.changeSlide(-1, 1);
        event.preventDefault();
    });
 
    $("#buttons a.button-next").bind("click", function (event) {
        Rotator.changeSlide(1, 1);
        event.preventDefault();
    });
 
    $("#buttons a.button-stop").bind("click", function (event) {
        if ($(this).html() == "Stop") {
            clearTimeout(timeOut);
            $(this).html("Play");
            //Set autostart because changeSlide use it            
            autostart = 0;
        }else {
            timeOut = setTimeout('Rotator.changeSlide(1, 0)', timeSeconds);    
            $(this).html("Stop");
            autostart = 1;
        }
        event.preventDefault();
    });
};

En esta función se creo el HTML para los botones y también se agregaron los eventos de clic. En los evento de clic simplemente se llama a la función Rotator.changeSlide y se le dice si se necesita el siguiente o el anterior elemento. También se utiliza el botón de Play o Stop para decidir si queremos que el slideshow se haga automático.

Como quedó la función de $(document).ready fue así:

$(document).ready(function () {
    //Set active first element and hide others
    $("#items p:first").addClass("active");
    $("#items p:not(:first)").hide();
 
    if (autostart) {        
        timeOut = setTimeout('Rotator.changeSlide(1, 0)', timeSeconds);    
    }
 
    if (buttons) {
        Rotator.makeButtons();
    }
});

Resumen

En este ejemplo hemos visto como con jquey podemos llamar a elementos del DOM de una manera muy fácil. También el uso de selectores como ":first", ":not" ":last" que permiten acceder directamente a elementos específicos.

Adjunto el ejemplo completo.

Su voto: Nada Promedio: 4.5 (31 votos)

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato

CAPTCHA
Esta pregunta es para probar si tu eres un humano y para prevenir spam en el sitio.
3 + 9 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.