Javascript: Slideshow con Jquery

Actualizado 2009-10-02: Se le añade botón de pausa (vaya fallo el no haberlo puesto anteriormente) y comentarios útiles sobre el funcionamiento de cada parte del código.

He creado un slideshow sencillo con Jquery (probado en versión 1.3.2):

jQuery.noConflict(); // Así podemos convivir con otras librerías JS como Prototype o Motools (y las que utilicen $) sin ningún conflicto

jQuery(document).ready(function(){
 var slides1 = new Slides();
  slides1.inicia();
  
 /*
 // Ejemplo de uso
 var slides1 = new Slides();
 slides1.inicia();
 slides1.caja = '#slides'; // id del contenedor de los destacados
 slides1.numero = 1; // Número de destacados que se muestran
 slides1.tiempo = 2.5; // Segundos entre cambio de destacado
 slides1.velocidadMostrar = 'fast';
 */
});

function Slides () {
 this.caja = '#slides'; // id del contenedor de los destacados
 this.slide = '.slide'; // destacado
 this.numero = 1; // Número de destacados que se muestran
 this.tiempo = 2.5; // Segundos entre cambio de destacado
 this.milisegundos = this.tiempo*1000; // No editar
 this.velocidadMostrar = 'fast';
 
 this.inicia = function () {
  
  numDestacados = jQuery(this.caja+' '+this.slide).length; // Número de destacados
  i=this.numero;
  k=0;
  
  // Se activa la primera tanda de destacados
  while (k<this.numero) {
   jQuery(this.caja+' '+this.slide).eq(k).addClass('activo');
   k++;
  }
  while (i<numDestacados) {
   jQuery(this.caja+' '+this.slide).eq(i).hide();
   i++;
  }
  
  // Se da ID a los destacados
  j=0;
  while (j<numDestacados) {
   jQuery(this.caja+' '+this.slide).eq(j).attr('id','slide-'+(j+1));
   j++;
  }
  
  this.paginacion(); // Se generan los controles de pausa y paginación
  
  // Se inicia el slideshow
  var that = this;
  this.intervalo = setInterval(function(){that.cambiar();}, this.milisegundos);
  
  // Al clicar una página se detiene el proceso y se va a la página
  jQuery('#paginadorSlide li a').click(function () {
   clearInterval(that.intervalo);
   that.controlPausar();
   that.irPagina(parseInt(jQuery(this).parent().attr('id').split('-')[1]));
   jQuery('#paginadorSlide li').removeClass('activo');
   jQuery(this).parent().addClass('activo');
   return false;
  });
  
  // Al clicar el botón de pausar/continuar se alterna detener/continuar el proceso
  jQuery('#pausarContinuar a').eq(0).click(function () {
   if (jQuery(this).hasClass('moviendo')) {
    that.controlPausar();
   } else {
    that.intervalo = setInterval(function(){that.cambiar();}, that.milisegundos);
    that.controlContinuar();
   }
   return false;
  });
  
 }
 
 // Modificar botón de pausar/reanudar
 this.controlPausar = function () {
  clearInterval(this.intervalo);
  jQuery('#pausarContinuar a').eq(0).html('Reanudar');
  jQuery('#pausarContinuar a').eq(0).removeClass('moviendo');
 }
 this.controlContinuar = function () {
  jQuery('#pausarContinuar a').eq(0).html('Pausar');
  jQuery('#pausarContinuar a').eq(0).addClass('moviendo');
 }
 
 // Cambiar de slide
 this.irPagina = function (pagina) {
  elUltimo = pagina*this.numero;
  el = (elUltimo)-this.numero;
  jQuery(this.caja+' '+this.slide).removeClass('activo');
  while (el<elUltimo) {
   jQuery(this.caja+' '+this.slide).eq(el).addClass('activo');
   jQuery(this.caja+' '+this.slide).eq(el).addClass('activo activoPausa');
   el++;
  }
  
  jQuery(this.caja+' '+this.slide+':not(.activo)').hide();
  jQuery(this.caja+' '+this.slide+'.activo').fadeIn(this.velocidadMostrar);
  
 }
 
 // Cambio automático de slide
 this.cambiar = function () {
  activos = jQuery(this.caja+' '+this.slide+'.activo').length-1;
  ultimoActivo = jQuery(this.caja+' '+this.slide+'.activo').eq(activos);
  numeroUltimoActivo = parseInt(jQuery(this.caja+' '+this.slide+'.activo').eq(activos).attr('id').split('-')[1])+this.numero;
  proximaPagina = (numeroUltimoActivo/this.numero)-1;
  numDestacados = jQuery(this.caja+' '+this.slide).length;
  
  if (numeroUltimoActivo>numDestacados) {proximoActivo=jQuery(this.caja+' '+this.slide).eq(0);proximaPagina=0;} else {proximoActivo = ultimoActivo.next(this.slide);}
  jQuery(this.caja+' '+this.slide+'.activo').removeClass('activo');
  i=0;
  while (i<this.numero) {
   proximoActivo.addClass('activo');
   proximoActivo = proximoActivo.next();
   i++;
  }
  jQuery(this.caja+' '+this.slide+':not(.activo)').hide();
  jQuery('#paginadorSlide li').removeClass('activo');
  jQuery('#paginadorSlide li').eq(proximaPagina).addClass('activo');
  jQuery(this.caja+' '+this.slide+'.activo').fadeIn(this.velocidadMostrar);
 }
 
 
 this.paginacion = function () {
  numPaginas = Math.ceil((jQuery(this.caja+' '+this.slide).length)/this.numero);
  jQuery(this.caja).after('<div id="controlesSlide"><ul class="paginadorSlide" id="paginadorSlide"></ul></div>'); // Se crea el contenedor de paginación
  jQuery('#paginadorSlide').before('<p id="pausarContinuar"><a href="#" class="moviendo">Pausar</a></p>'); // Se crea el párrafo para el botón de detener/continuar en su estado predeterminado (Pausar)
  
  i=0;j=1;
  while (i<numPaginas) {
   jQuery('#paginadorSlide').append('<li id="paginaSlide-'+j+'"><a href="#">'+j+'</a></li>');
   i++; j++;
  }
  jQuery('#paginadorSlide li').eq(0).addClass('activo');
 }
 
}

Para iniciarlo con los id y clases predeterminados:

var slides1 = new Slides();
 slides1.inicia();

En ese caso el HTML podría ser:

<div id="slides">
 <div class="slide">
  [Contenido del slide]
 </div>
 <div class="slide">
  [Contenido del slide]
 </div>
</div>

Un contenedor que lleve el id slide y elementos dentro del mismo con la clase slides.

Ver demostración o descargar el ejemplo (archivo ZIP, 348KB).

19 respuestas a «Javascript: Slideshow con Jquery»

  1. Amigo me ha sido de mucha ayuda tu explicación de slide, te agradezco. Tengo una sola duda, qué función hay que modificar para que no se suba la página, por ejemplo cuando está en la parte más baja de la página y cambia la imagen, la pantalla se devuelve a la cabecera de la página, gracias, espero me puedas ayudar.

  2. Me ha servido de mucho tu codigo lo voy a revisar y ver que se le puede modificar para que sea mas optimo aunque no creo que se le tenga que modificar nada saludos

  3. Como no tiene nada de flash, es muy ligero para la carga de las páginas.

    Es perfecto para un blogroll dinámico y que no ocupa casi espacio, más que el del propio visor.

    Me ha gustado, lo utilizaré, con tu permiso.

    Muchas gracias por compartirlo.

    Un saludo.

  4. Va de maravilla, pero tengo un problema, lo he puesto en la parte inferior de una web y cada vez que pasa de imagen se sube arriba de la web, como si la recargará la página, y no se pueden seguir viendo las fotos, ya que hay que hacer scroll hacia abajo, y cuando cambia de foto, otra vez se vuelve a subir, y volvemos a empezar ese ciclo. ¿Alguna solución?

  5. En el ejemplo también se sube. Para ese caso habría que darle por CSS una altura fija al DIV con id=»slides», que es el contenedor de las distintas capas que aparecen y desaparecen.

  6. Lo acabo de pobar y no funciona, ni poniendo el div con id=»slides» en position: absolute ni con relative, he probado con las 2 por si acaso 🙁

    ¿Se te ocurre alguna otra solución?

  7. Me refería a la propiedad ‘height’. En el bloque que hay arriba del todo a la derecha (‘Outbook en Twitter’) he utilizado el mismo script de este artículo, y la diferencia que tiene con el ejemplo es que se le ha definido la propiedad ‘height’ en CSS. Con el ejemplo al que se enlaza en el artículo he probado haciendo el cambio con Firebug y lo dejaba de hacer.

  8. He actualizado la CSS del ejemplo y la del descargable para que no se cambie sola la posición de la página.

  9. Exelente articulo! Es justo lo que necesitaba. Tengo solo una duda. Estoy comenzando recien con JQuery y necesitaria poder agregar dos botones para poder ir al slide anterior y al siguiente. Hay forma de hacerlo con este script? Alguien me podria dar una mano? Desde ya les agradezco muchisimo!!

  10. hola quiero utilizar tu javascript pero quiero jalar las fotos desde una base de datos, ya tengo las galeria pero solo kiero aplicar tu javascript y la vdd no tengo idea de como combinar el resultado de mi consulta con tu aplciacion. la verdad me ayudarias mucho.
    Gracias De Antemano.

  11. Está genial tu código, fácil de comprender y de usar.

    Te agradezco mucho tu aportación.

    Para fijar el slide a una determinada posición, en el css solo modifiquen #slides slide y agregen position:relative;

    Saludos

  12. Me parece fantastico, pero que propiedad hay que tocar para hacer la transición entre imagenes más suave, que no peque un salto, sino que se funda con la siguiente, es posible?

  13. Estoy probando tu jquery, pero sigue llendo al arriba nuevamente el sitio cuando cambia de imagen. Probe con lo que decis del css nuevo y el height y sigue haciendolo igual…tenes una solucion a esto?

  14. Muy bueno . Lo he usado , y me he permitido la licencia de ampliarlo, poniendole una variable privada mostrarPaginacion, para controlar la muestra o no de los controles de paginacion.

  15. Felicitaciones, este slide es excelente, lo acabo de probar con ietester y valla sorpresa, funciona en ie6, increíble.
    Muchas gracias por el tutorial.

    Un saludo.

  16. respondo a «flojo». para que no pegue el salto edita el css.

    #contenedor {background-color:#fff; margin:1em auto; padding:1em; width:32.4em;
    position:relative;
    }
    #slides .slide {
    min-height:23.6em;
    position:absolute;
    top:0; left:0;
    }

    se te descuadrara el diseño pero ya no saltará, luego es cuestión de que sigas tocando el css para dejarlo a tu gusto.

  17. para que la transicion sea mas suave, ve a la linea 121 del codigo js y reemplazala por esta otra:

    jQuery(this.caja+’ ‘+this.slide+’:not(.activo)’).fadeOut(2000);

    donde 2000 equivale a 2 segundos

  18. Buenas tardes, una pregunta ¿Si quieserámos que empezara por la imagen nº3 por ejemplo, qué variaría en el código?

Los comentarios están cerrados.