Carrusel de imágenes con efecto de fundido (y en menos de 2Kb)

Programamos un script que convierte una lista en un carrusel de diapositivas con un efecto de transición de fundido.


No hace tanto, explicábamos cómo habíamos vuelto flexible un plugin de jQuery que consiste en un carrusel de imágenes. En esta entrada mostramos una versión que hemos programado desde cero, con un efecto diferente y que no depende de ninguna librería.

El carrusel de imágenes no sólo es un elemento que ahorra espacio de diseño en una página a la hora de presentar una galería de imágenes: es, además, una manera muy eficiente de ofrecer en la portada de un sitio web lo que Douglas K. van Duyne denomina up-front value proposition (‘propuesta de valor directa’)1.

No obstante, nos dimos cuenta de que sólo por lograr ese efecto no merece la pena cargar una página con el peso adicional de jQuery y el plugin si el resto del sitio no necesita de las ventajas que ofrece la librería. Por eso pensamos que sería genial disponer de un script lo más ligero posible que ofreciera la misma funcionalidad. Y como no nos convencía ninguno de los que encontrábamos, decidimos programar uno.

Los requisitos los teníamos bastante claros:

Nuestro carrusel

Dicho y hecho. La verdad es que estamos bastante contentos con el resultado, y aquí puede verse una demostración en todo su esplendor.

Detalle del carrusel [Firefox 3.6]

El script, sin dependencias

He aquí el script:


var DP = {
  ds: '',
  dA: 0,
  sD: 0,
  tD: 0,
  t: 3000,
  idD: 'diapos',
  nID: 'diapos-on',
  idC: 'contador',
  clC: 'actual',
  IE: false,
  anim: true,
  intv: '',
  lnz: '',
  $: function(el){
    var e = document.getElementById(el); return e;
  },
  op: function(el,v){
    (DP.IE) ? el.style.filter='alpha(opacity='+v+')' : el.setAttribute('style','opacity:'+v/100);
  },
  ac: function(c){
    DP.$(DP.idC).getElementsByTagName('li')[DP.dA].className=c; 
  },
  fun: function(){
    var i = 100;
    (DP.dA==DP.tD) ? DP.sD = 0 : DP.sD = DP.dA+1;
    DP.intv = setInterval(function(){
      i = i-5;
      if(i>=0){
        DP.op(DP.ds[DP.dA],i);
        DP.op(DP.ds[DP.sD],(100-i));
      } else {
        DP.ac('');
        (DP.dA==DP.tD) ? DP.dA = 0 : DP.dA++;
        DP.ac(DP.clC);
        clearInterval(DP.intv);
        if(DP.anim){DP.lnz = setTimeout(DP.fun,DP.t);}
      }
    },50);
  },
  manual: function(d){
    clearInterval(DP.intv);clearTimeout(DP.lnz);DP.anim=false;
    DP.op(DP.ds[DP.dA],0);
    DP.op(DP.ds[d],100);
    DP.ac('');
    DP.dA=d;
    DP.ac(DP.clC);
  },
  inicio: function(){
    (navigator.userAgent.match('MSIE')) ? DP.IE = true : DP.IE = false; 
    DP.$(DP.idD).id=DP.nID;
    DP.ds = DP.$(DP.nID).getElementsByTagName('li');
    DP.tD = DP.ds.length-1;
    var ct = document.createElement('ul');
    ct.id = DP.idC;
    (DP.$(DP.nID).nextSibling) ? (DP.$(DP.nID).parentNode).insertBefore(ct,DP.$(DP.nID).nextSibling) : (DP.$(DP.nID).parentNode).appendChild(ct); 
    for(var i=0;i<=DP.tD;i++){
      DP.op(DP.ds[i],0);
      DP.$(DP.idC).innerHTML += '<li><a href="#" onclick="DP.manual('+i+')">'+(i+1)+'</a></li>';
    }
    DP.op(DP.ds[0],100);
    DP.ac(DP.clC);
    DP.lnz = setTimeout(DP.fun,DP.t);
  } 
}
	

Las variables que se pueden configurar son:

En cuanto a la CSS, los estilos que exige son mínimos:


#la-lista{ position:relative; }
#la-lista li{ position:absolute:top:0;left:0;}
	

Y, por último, con respecto a la compatibilidad, funciona en Firefox 2.0+, Safari 3.0+, Opera 9.25+, Chrome 1.0+ y Explorer 6+.

Degradación elegante y cuestiones de accesibilidad

En la mayoría de los scripts que ojeamos antes de programar el nuestro vimos que la solución más común al problema de la falta de soporte de JavaScript consiste en hacer que las diapositivas aparezcan en un contenedor con su propia barra de desplazamento. Pero para no tomar la decisión por el desarrollador que use nuestro script, hemos optado por una solución diferente: asignar un nuevo id a la lista animada. ¿Para qué? Para permitir que en la CSS se puedan aplicar estilos independientes al contenedor cuando JavaScript esté disponible y para cuando no lo esté. Así, el control sobre el aspecto de la página degradada sigue siendo del autor.

Por ejemplo, en la demostración anterior, las imágenes aparecen simplemente una debajo de otra cuando el cliente no dispone de soporte para JavaScript. En esta otra, mantenemos la lista en su posición y le añadimos por medio de un estilo una barra de desplazamiento que permite el acceso a los elementos de la lista.

Y en cuanto a la accesibilidad, hemos tenido en cuenta los puntos de las WCAG 2.0 relevantes para este script:

Sí, en menos de 2Kb

Concretamente, el .js pesa 1,63Kb, aunque se puede minimizar y se queda en 1,37.

Aviso: el script se entrega «tal cual»…

…lo que quiere decir que el script sólo hace lo que hace. Sí, hay otros scripts en la red para los que se puede configurar opciones como el tipo de transición —fundido, desplazamiento horizontal o vertical—, reinicio automático, etc., pero eso habría incrementado el peso del .js, y queríamos ajustarnos al límite de los 2Kb. No obstante, tenemos intención de publicar otras versiones con efectos distintos para quien los necesite.

Notas

  1. Douglas K. van Duyne, James A. Landay y Jason I. Hong: The Design of Sites. Patterns for Creating Winning Web Sites, 2.ª edición, Prentice Hall, Nueva Jersey, 2007.

Esta entrada se publicó el 13 de mayo de 2010, se archivó en , y fue etiquetada como efectos javascript, en menos de 2Kb, javascript no obstrusivo. Autor: Saúl González Fernández. Hay 98 comentarios ›.

Comentarios

  1.  rider mendez dice:

    Excelente el tutorial, buena esa por la nota al final.

  2.  angel dice:

    Disculpa, ¿y las imagenes en que lugar van en el codigo?

  3.  Saúl González dice:

    En el código tienes que crear una lista con un id que es el que luego asignas a la variable idD del script. Cada li de la lista es el que incuye una imagen.

    En nuestro ejemplo el código es:

    
    <ul id="diapos">
      <li><img src="01.jpg" alt="" width="700" height="350" /></li>
      <li><img src="02.jpg" alt="" width="700" height="350" /></li>
      <li><img src="03.jpg" alt="" width="700" height="350" /></li>
      <li><img src="04.jpg" alt="" width="700" height="350" /></li> 
    </ul>
     
  4.  Jorge Saucedo Crespo dice:

    Saludos. Primeramente gracias por el aporte.

    He estado haciendo pruebas para ingresar imagenes y no he tenido problemas, pero tengo un problema: ya he intentado mover los valores y no logro que el carrusel (las imagenes) se posicionen al top de la tabla donde las ubico, es decir, siempre me deja un espacio aproximado de 150 pixels libre desde el primer renglon de la tabla o bien de cualquier texto que ponga por encima del carrusel, y esto me genera un espacio que se ve mal en mi pagina.

    Espero que puedan indicarme que estoy haciendo mal o que podrá estar pasando.

    De antemano ¡gracias!

  5.  Saúl González dice:

    Si has empleado el estilo que hemos incluido en la página de ejemplo, es posible que ese espacio se deba a una de las reglas aplicadas a #diapos-on, concretamente margin:5em auto 0;. Prueba sustituir el valor de 5em por 0.

    En otro orden de cosas, te recomendaría que no empleases tablas para maquetar tu página; tus usuarios discapacitados te lo agradecerán, y el marcado será más correcto semánticamente.

  6.  Manoli dice:

    ¡¡¡Muchísimas gracias!!!
    Justo lo que buscaba.
    En pocas palabras fácil, rápido y explicado de una manera tan clara y sencilla que debería estar incentivado de algún modo.

  7.  gabino gomez dice:

    Buenas. Muchas gracias por tu aporte, pero una pregunta: ¿cómo hago para que al comenzar las fotos no aparezcan como un listado sino que sólo aparezcan cuando ya este montada en el cuadro blanco? Muchas gracias.

  8.  Joe dice:

    Disculpen, ¿dónde pongo el codigo? Soy novato.

  9.  Saúl González dice:

    @Gabino Gómez:

    Puedes posicionar las imágenes ya superpuestas por medio de CSS, aunque el problema con esta solución es que los usuarios que no tengan JavaScript activado sólo podrán ver una de las imágenes.

    @Joe:

    Todos los navegadores cuentan con la opción de ver el código de una página web. En Firefox 3.6, por ejemplo, es Ver > Código fuente de la página (o simplemente Ctrl + U). Hazlo en la página del ejemplo y ahí podrás ver cómo lo hacemos.

  10.  Ruth dice:

    El script me funciona perfectamente, hasta que intento colocar el estilo en un documento .css externo, ¿por qué?

    Soy un poco bastante novata, en este tema… y no sé solucionarlo.

    Me gustaría hacerlo de ese modo porque quería aplicar el mismo estilo a varias páginas.

  11.  Saúl González dice:

    Comprueba que en el head de la página estás incluyendo correctamente el vínculo a la hoja de estilo:

    
    <link rel="stylesheet" href="ruta_del_css" type="text/css" media="screen" /> 
     
  12.  caco dice:

    Hola, súper bueno el JS. Una pregunta, ¿se puede cambiar el ancho y el alto del marco blanco, osea, ajustarse a otro tamaño de imagen? ¿Me puedes contar, por favor?

    Mvc
    ¡Saludos y felicitaciones!

  13.  Saúl González dice:

    Hay dos elementos que afectan al tamaño del recuadro: uno es el tamaño de las imágenes —si estas están incluidas en el marcado—, y el otro es el estilo aplicado a los li del carrusel:

    
    #diapos-on li{position:absolute;top:0;left:0;width:700px;height:350px;list-style:none;} 
     

    Asigna en ambos los valores que necesites.

  14.  Ruth dice:

    Muchísimas gracias Saúl, efectivamente el problema era que no puse correctamente el vínculo hacia la hoja de estilo. Ahora el script funciona perfectamente.
    Le he dado un toque personal colocando una imagen blanca del mismo tamaño en el fondo para que no trasparente el fondo (en mi caso no es liso).
    Os invito a que veais el asombroso resultado en mi web de este magnífico script: http://monrut.com/Reloj_Pared_R005.htm

  15.  Beatriz dice:

    ¡¡Hola, qué maravilla de código!! Enhorabuena ?
    Tengo una pregunta, estoy probando a poner en cada imagen un enlace, pero sólo consigo que funcione el de la foto 4. ¿Cómo puedo hacerlo?

  16.  Saúl González dice:

    Para corregir ese comportamiento, publicamos una nueva versión del carrusel. Pesa un poco más, pero sigue sin llegar a 2Kb ?

  17.  victor manuel dice:

    En Explorer no se ve la sombra del contorno. ¿Puede solucionarse?

  18.  Saúl González dice:

    La sombra la aplicamos con la propiedad box-shadow de CSS3 —y sus equivalentes con los prefijos -moz- y -webkit-—. Explorer 9 ya soporta la propiedad, pero las versiones anteriores no. Si necesitas reproducir el efecto en éstas, tienes un par de opciones.

    La primera es emplear filtros de Microsoft, en este caso añadiendo en la CSS al selector #diapos-on:

    
    filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='20',MakeShadow='true',ShadowOpacity='0.50'); 
     

    El resultado no será exactamente el mismo, pero se acercará bastante.

    Tu segunda opción es emplear un archivo .htc que reproduzca el efecto de box-shadow como el que hay alojado en Google Code.

    No obstante, en mi modesta opinión, la sombra no es más que un añadido del que puedo prescindir en navegadores antiguos y que no merece que me dedique a buscar maneras de evitar que mi hoja de estilo sea inválida.

    La decisión de emplear o no los parches depende de la respuesta a esta pregunta: ¿el aspecto de un sitio web debe ser exactamente el mismo en todos los navegadores?

  19.  Javier dice:

    Hola te felicito por tu aporte, pero te planteo un problema que me parece bastante gordo a mi parecer.

    El problema es que si queremos mostrar unas 20 o más fotos hay que cargarlas todas de golpe y no es viable por el peso y el tiempo de carga.
    Está bien para 4 o 5 imagenes y de tamaño reducido pero para más no.

    Ademas queda muy feo y molesto que se vea un relampagueo de las imágenes en forma de lista al abrir la pagina en el lado izquierdo y luego desaparezcan, el relampagueo es más largo cuantas mas imagenes hay y dependiendo de su tamaño.

    Debrias mejorar el script para que cargara las imágenes externamente por separado, por ejemplo cargar la foto1 hacer un fadeIn y poner a cargar la foto2 una vez cargada hacer un fadeOut a la foto1 y realizar el fadeIn a la foto2 y poner a cargar la foto3 y asi succesivamente.

    Saludos.

  20.  Saúl González dice:

    @Javier:

    Muchas gracias por la indicación, pero creo que ha habido un malentendido con respecto al objetivo y la utilidad del script. Como digo en la introducción de la entrada, está pensado precisamente para tres o cuatro imágenes que sirvan como propuesta de valor inicial de un sitio, por ejemplo, ofreciendo los servicios más destacados de una empresa. En ningún momento pretende ser una interfaz para una galería de imágenes completa, caso en el que, efectivamente, la solución de la carga en secuencia sería la opción óptima.

    Precisamente por la importancia del contenido de esa propuesta inicial, preferimos que los contenidos totales se carguen inicialmente, para que en el hipotético caso de que un usuario no cuente con soporte de JavaScript no pierda nada de la información.

    A partir de ahí es tarea del diseñador competente organizar los contenidos para cuando se presentan de forma simultánea —con selectores de CSS a partir del id inicial del carrusel—, y de forma consecutiva —por medio del nuevo id asignado al mismo elemento—, cuando JavaScript está activo.

    Un saludo.

  21.  Jorge dice:

    Como bien han dicho todos el tutorial buenísimo, otra pregunta al caldero, ¿hay alguna forma sencilla de quitar el contador de seleccion manual?, gracias.

  22.  Saúl González dice:

    @Jorge: La manera sencilla sería aplicar un display:none al contador, pero eso no eliminaría el código generado innecesariamente. Tendrías que borrar los elementos del script que tienen que ver con el contador.

    Te dejamos abajo el código simplificado:

    
    var DP = {
      ds: '',
      dA: 0,
      sD: 0,
      tD: 0,
      t: 3000,
      idD: 'diapos',
      nID: 'diapos-on',
      IE: false,
      anim: true,
      intv: '',
      lnz: '',
      $: function(el){var e = document.getElementById(el);return e;},
      op: function(el,v){(DP.IE) ? el.style.filter='alpha(opacity='+v+')' : el.setAttribute('style','opacity:'+v/100);}, 
      fun: function(){
        var i = 100;
        (DP.dA==DP.tD) ? DP.sD = 0 : DP.sD = DP.dA+1;
        DP.intv = setInterval(function(){
          i = i-5;
          if(i>=0){
            DP.op(DP.ds[DP.dA],i);
            DP.op(DP.ds[DP.sD],(100-i));
          } else {
            (DP.dA==DP.tD) ? DP.dA = 0 : DP.dA++;
            clearInterval(DP.intv);
            if(DP.anim){DP.lnz = setTimeout(DP.fun,DP.t);}
          }
        },50);
      },
      inicio: function(){
        (navigator.userAgent.match('MSIE')) ? DP.IE = true : DP.IE = false;
        DP.$(DP.idD).id=DP.nID;
        DP.ds = DP.$(DP.nID).getElementsByTagName('li');
        DP.tD = DP.ds.length-1;
        for(var i=0;i<=DP.tD;i++){DP.op(DP.ds[i],0);}
        DP.op(DP.ds[0],100);
        DP.lnz = setTimeout(DP.fun,DP.t);
      }
    }
     

    No obstante, te recomendaríamos que no lo eliminaras, para dejar al usuario un método por el que controlar ese movimiento, según indican las Pautas de Accesibilidad 2.0 del W3C en el punto 2.2.2.

  23.  Jorge dice:

    Gracias por el aporte, no sé si lo han comentado, pero ese segundo de carga en el que se ven las imágenes descolocadas, ¿cómo se solucionaría? Repito, muchas gracias por el aporte.

  24.  Jorge dice:

    En la página de ejemplo también pasa que salen un segundo como en una lista.

  25.  Saúl González dice:

    @Jorge: La cuestión de las imágenes ya la hemos comentado aquí. Échale un ojo.

  26.  Jorge dice:

    Gracias, sí ok.

  27.  eduardo dice:

    Hola, inserté el código y funciona perfecto, pero inserté arriba una tabla y ahora entre el efecto blanco y las imagenes me deja un espacio. Ya cambié en #diapos-on, concretamente margin:5em el 5 por un 0, pero me sigue apareciendo el espacio. Ojalá me puedan ayudar.
    Saludos

  28.  jorge dice:

    Una pregunta más, si no es mucha molestia, al pasar a modo manual se para el fundido automático entre las imágenes, ¿cómo se podria iniciar de nuevo éste? Ejemplo: pulsando la misma imagen que comenzase a fundir automaticamente de nuevo. Gracias.

  29.  Saúl González dice:

    @eduardo: Es posible que la tabla tenga un margen inferior. Prueba asignarle a ésta un margin-bottom:0; ver si se trata de eso…

    @jorge: No es mala idea, aunque habría que cambiar el código. Lo tendremos en cuenta si hacemos una nueva versión.

  30.  Sebastián Botero dice:

    Excelente código, ¿hay alguna posibilidad de ponerle un texto a las imágenes traído de un archivo XML?

  31.  Alex-8 dice:

    Es un aporte genial, pero en mi caso tengo un problema.

    He hechos varias modificaciones, intentando adaptar el carrusel dentro de una página determinada y no tengo problemas con Mozilla ni con Google Chrome; pero en el caso de Internet Explorer me queda un amplio espacio inferior que no sé cómo solucionar, por más vueltas que le doy. Te dejo aquí el código completo de esta página con el código del carrusel incluido dentro:

    [CÓDIGO ELIMINADO POR EL EDITOR]

    Te agradecería muchísimo que pudieras ayudarme a quitar ese espacio. Gracias.

    Nota: quizás tenga que ver con el hecho de que eliminé el contador de selección manual.

    Un saludo.

  32.  Saúl González dice:

    @Sebastián Botero: por supuesto, en el segundo ejemplo hemos hecho la prueba de incluir un texto; valdría, por ejemplo, para incluir un pie de foto. Sobre cómo extraerlo del XML, bien podrías hacerlo por medio de PHP para incluirlo en el código inicial de la página, bien cargándolo con una función adicional de JavaScript.

    @Alex-8: el código no se presenta completo por los filtros de los comentarios que tenemos activos. Si puedes proporcionarnos una URL donde podamos ver la página funcionando quizá podamos ayudarte.

  33.  Alex-8 dice:

    Saúl:

    Antes de nada, pedirte disculpas por poner el código entero.

    He «colgado» una breve página de muestra en la que he ubicado el carrusel de imágenes. Como puedes ver, he modificado varias cosas respecto al original: he eliminado el contador de selección manual, he quitado el marco, he cambiado el fondo (dejándolo blanco) y he integrado el carrusel en la columna izquierda de una tabla (quiero aprovechar el espacio que me brinda la columna derecha para informaciones puntuales).

    La URL donde puedes ver el resultado es ésta: http://www.terra.es/personal4/inforstj/prueba/contacta.html

    Como podrás coprobar en Mozilla, Chrome, Safari… no queda ningún espacio más amplio de lo normal debajo del carrusel de imágenes; mientras que en Internet Explorer (yo tengo la versión 8), queda un espacio exagerado debajo del carrusel.

    Por más pruebas y cambios que he hecho, no acierto a quitar ese espacio vacío.

    Te agradecería mucho que pudieras ayudarme.

    Recibe un cordial saludo.

  34.  Saúl González dice:

    @Alex-8: en efecto, el problema está en el contador; eliminaste la numeración que se muestra, pero se sigue generando una lista vacía para contenerla. Prueba sustituir el código del documento de JavaScript con el que publicamos arriba para Jorge, y no debería haber problema.

    Aparte de eso, te recomendaría que no crearas tus páginas maquetándolas con tablas, así separarás mejor el contenido de la presentación y mejorarás mucho la accesibilidad del sitio. Si estás empezando a hacer webs, tal vez te sea útil un curso que escribí hace unos años. Como es un proyecto un poco antiguo hay partes que están un tanto obsoletas —no vas a encontrar nada de HTML5 ni CSS3 ahí—, pero creo que puede darte una buena base para que luego puedas seguir aprendiendo por tu cuenta.

  35.  Alex-8 dice:

    Saúl:

    Tenías razón: ahora ya sin problemas; todo funciona perfectamente y en todos los navegadores. Ya había visto antes el código simplificado que publicaste para Jorge pero, en mi ignorancia, no fui capaz de comprender que ese código era el contenido del archivo «DP.js». Ya había eliminado lo que tenía que ver con el contador, pero lo hice sólo en la página, no en el documento «DT.js».

    Respecto al curso que me recomiendas, le he echado un vistazo por encima y creo que me va a venir «más que bien». Espero que lo dejes ahí «colgado» durante cierto tiempo para ponerme con él a ratos.

    Muchísimas gracias por toda tu ayuda y enhorabuena por el blog. Estás haciendo un buen trabajo.

  36.  Tomás dice:

    ¡Hola! Muchísimas gracias por el ejemplo. Estoy intentando aprender a realizar páginas webs por mi cuenta y me ha sido de mucha utilidad, aunque quiero poner dos carruseles en la misma página y no sé cómo hacerlo. ¿Podrías ayudarme?

    Muchísimas gracias ?

  37.  diana dice:

    Hola, gracias, me sirvió el script. A pesar de ser la primera vez que uso uno lo pude configurar a mi gusto y quedo muy bien (cambio de colores tamaños, etc.)

    ¿Cómo hago para que las imagenes se carguen antes y no se vean una abajo de otra sino directamente fundiéndose?

    Vi que alguien pregunto lo mismo pero no entiendo cómo hacer para solucionarlo.

    ¿Con CSS? Si me podés ayudar te agradezco.

    Saludos.

  38.  Saúl González dice:

    @Tomás: El script está pensado para un único carrusel en la página, así que sería difícil lograr el efecto que necesitas sin reprogramaslo o sin duplicarlo…

    Tal vez te sea de utilidad probar con alguno de los plugins que hay para jQuery; el que me parece más completo es Nivo Slider —la versión sin soporte es gratuita—, pero tiene la desventaja de que vas a cargar un poco tu página con la biblioteca y el plugin mismo.

  39.  Saúl González dice:

    @diana: Disculpa que hayamos tardado en contestarte, pero es que queríamos que vieras de ejemplo un caso real. Acabamos de publicar la página de un cliente —http://www.midietistapersonal.es—, en la que hemos incluido en la portada un carrusel de imágenes.

    Cuando un usuario llega a la página y el script aún no funciona —o si el agente de usuario no soporta JavaScript— lo que se ve es esto (JPEG, 204Kb): la información del carrusel está completa para el visitante, como una lista.

    En cuanto el JavaScript comienza a ejecutarse, se convierte en el carrusel (JPEG, 204Kb).

    Si echas un vistazo a la hoja de estilos, verás que lo hacemos aplicando dos conjuntos de reglas alternativos, uno para #diapos que se interpretan mientras el script no se ejecuta, y el otro para #diapos-on cuando sí lo hace.

    Creemos que esta solución es mejor que la precarga de las imágenes.

  40.  Joanpasc dice:

    Hola, te felicito por el aporte, pero tengo una duda. ¿Sería posible que los cuadros pequeños de posición fuesen miniaturas de las diapositivas?

    Un saludo

  41.  Emma dice:

    Yo quiero esto pero que se pasen las fotos solas, ¿alguien sabe? Que se fundan o se pasen de una a otra de alguna manera.

  42.  Saúl González dice:

    @Joanpasc: Sí, es posible que los cuadros muestren una miniatura.

    Su aspecto se define en la hoja de estilo de la página, así que puedes darles un tamaño mayor al que hemos asignado nosotros en nuestro ejemplo y especificar como fondo una imagen que sea la miniatura. Sólo un detalle: necesitarías hacer una pequeña modificación al script en la línea que define el marcado de los ítems del contador:

    
    <li id=con"'+i+'"><a href="#" onclick="DP.manual('+i+')">'+(i+1)+'</a></li> 
     

    Añadiendo el id=con"'+i+'", ahora a cada cuadro le puedes poner un fondo distinto con los selectores #con1, #con2, etc.

    @Emma: Disculpa, pero la animación ya se ejecuta de manera automática… Si no es así, igual es un problema con el navegador, ¿nos podrías decir cuál estás empleando? Muchas gracias.

  43.  Jorge dice:

    Hola de nuevo, tengo una duda: ¿si quisera hacer que el encadenado fuese mas lento se podria poner una variable para controlar esta acción?
    Gracias.

  44.  Saúl González dice:

    @Jorge: No estoy seguro de a qué te refieres exactamente, pero voy a intentar contestar.

    Si te refieres al tiempo que transcurre entre el fundido de una imagen y la siguiente, se controla por medio de la variable t, que inicialmente definimos con un valor de tres segundos —t: 3000—. Ese es el tiempo que una imagen es visible desde que acaba el fundido hasta que comienza de nuevo.

    Si te refieres al tiempo que dura la transición —es decir, la duración del efecto de fundido en sí—, no tenemos una variable definida específicamente, pero puedes modificar el tiempo del setInterval() de la función fun(); ahora está establecido a 50 —justo antes del cierre de la función—: valores mayores ralentizarán el efecto.

    Espero haberte resuelto la duda.

  45.  Jorge dice:

    Gracias, eso es.

  46.  Rodrigo dice:

    Impresionante.

    He visto que al hacer clic en un contador la animación se para, por lo menos cuando yo lo he implementado.

    ¿Sería muy dificil que la animación continuara y añadir un botón de pausa y play?.

    Gracias.

  47.  Saúl González dice:

    @Rodrigo: Sí, incluimos esa funcionalidad del contador para cumplir con la pauta 2.2.2 de las WCAG2.0, que dice que hay que proporcionar un mecanismo para que el usuario pueda detener los objetos en movimiento.

    No sería difícil sustituirlo por un botón de reproducción/pausa… si logramos hacerlo en menos de 2Kb lo publicaremos. ?

  48.  Pedro dice:

    Me parece estupendo el trabajo que habéis realizado, pero noto que al cargar la página, las imágenes aparecen en vertical una tras otras, hasta que termina de cargarse totalmente el carrusel. ¿Hay alguna forma de evitar esto?. Cuando la conesión de Internet es rápida apenas se nota este efecto, pero cuando la página tarda en cargarse se hace molesto.

    ¡¡Muchas gracias por vuestro aporte!!

  49.  Saúl González dice:

    @Pedro: Como mencionábamos en un comentario anterior, lo hemos hecho así para permitir que los usuarios reciban toda la información en caso de que su cliente no tenga soporte de JavaScript.

  50.  Pedro dice:

    Muchas gracias Saúl por tu aclaración y por el ejemplo que muestras.

    Perdona mi ignorancia. ¿Hay alguna manera de modificar el código del script para que las imágenes no se muestren en vertical hasta que se cargue el código totalmente?

    Aunque ya me explicas, razonablemente, que el script lo habéis realizado a propósito para que se muestren todas las imágenes en el caso de que el cliente no soporte JavaScript, en mi caso, por el diseño de las imágenes, prefiero que no se cargue el carrusel y que el cliente no lo vea, antes de que se muestren todas las imágenes en vertical y me modifique la presentación de la Web.

    Muchas gracias de nuevo. Recibe un cordial saludo.

  51.  Saúl González dice:

    @Pedro: Se podría reprogramar el script para que cargue las imágenes, cree el carrusel, y después se inserte o sustituya un elemento de la página. En cuanto saquemos tiempo lo programaremos, prometido.

  52.  Pedro dice:

    Buenas tardes Saúl.

    He encontrado solucción a la cuestión que te planteaba.

    Sin modificar el script, se puede conseguir el efecto que deseaba cambiando en el html una línea de código.

    (Este código va en el body de la web, donde figuran los enlaces de las imágenes.)

    Sustituye la línea:

    <ul id="diapos">

    Por esta otra:

    <ul id="diapos" style="height:165px;overflow:hidden">

    (165 es el alto de mis imágenes de ejemplo.)

    Espero que os pueda servir a todos los que buscábais el efecto que pretendía yo.

    Gracias por tu atención y por el trabajo realizado.

  53.  Manolo dice:

    Hola, antes de nada agradecerte el aporte, hace tiempo que buscaba hacer esto y me ha servido de mucha ayuda. Me gustaría hacer una pregunta aunque sea una tontería pero ¿cómo cambio el color del fondo? GRACIAS.

  54.  Saúl González Fernández dice:

    @Manolo: Todo lo que tiene que ver con el aspecto está definido en la hoja de estilo; para el color se trata de la propiedad background de los elementos.

    Por cierto, si el contenido que estás incluyendo en las «diapositivas» cuenta con vínculos, es posible que prefieras utilizar el código de la segunda versión.

  55.  Manolo dice:

    Saul, Gracias ya habia visto la segunda versión y es la que quiero instalar en la web, pero sigo sin dar con la tecla para cambiar el color del fondo, cuando dices que esta en la hoja de estilos la propiedad background, ¿a qué te refieres? Soy muy pero que muy novato y perdona si te pregunto algo demasiado obvio.

    Gracias por tu atención y gracias por aportarnos el codigo.

  56.  Saúl González Fernández dice:

    @Manolo: No te preocupes, para aprender primero hay que dudar ?

    Si miras el código del ejemplo, verás que hay una línea que es body{color:#FFF;background:#333 url(fondo.png) left top repeat-x;}; los valores tras # son un código hexadecimal que indican el color que se quiere aplicar. Por lo general es un grupo de seis caracteres, pero aquí lo abrevio; en la Wikipedia tienes una lista de colores disponibles.

    Como indicaba en un comentario anterior, si necesitas un poco más de información, hace años escribí un curso que te puede servir de base; ésta es la parte de CSS, aunque igual te viene bien echarle una ojeada al completo.

    Espero que te sirva de ayuda.

  57.  Jesús Iván dice:

    Hola. Este es el mejor ejemplo que me ee encontrado… ¡y vaya que he buscado!

    Nada más una cosa para los que vamos empezando en esto y queremos darle algo de lucidez a nuestras web… ¿tu ejemplo no está disponible para descarga?

    Si no está disponible cómo lo podemos hacer para emplear en una web con nuestras propias imágenes?

  58.  Saúl González Fernández dice:

    @Jesús Iván: No te preocupes, te mando un .zip al correo que nos has proporcionado.

  59.  Jesús Iván dice:

    OK. Muchísimas gracias.

  60.  Carlos dice:

    Excelente el código, muy breve y conciso. Justo para solucionar la necesidad de carrusel en las paginas de inicio.

    Gracias por el aporte.

  61.  Yolanda Torre dice:

    Hola: Estoy probando a cambiar el contador por unas miniaturas y no sé cómo hacerlo… ¿podríais echarme un cable?

    hacer una pequeña modificación al script en la línea que define el marcado de los ítems del contador:
    <a href=»#»>’+(i+1)+'</a>

    ¿en el body?, ¿después de cada li?, ¿después del ul?, ¿entre cada una?

    Añadiendo el id=con»‘+i+'», ahora a cada cuadro le puedes poner un fondo distinto con los selectores #con1, #con2, etc.

    ¿Sería así?: id=con"'1'" id=con"'2'".

    Lo cierto es que no me sale…

    ¡Felicitaros por vuestro trabajo y por vuestra generosidad!

  62.  Yolanda Torre dice:

    La línea de los items de contador está en el archivo DP.js, esto creo que lo tengo bien.

    Tengo los cuadros con el tamaño y una miniatura, el problema es que la miniatura se repite para todos los cuadros.

    
    #contador li a{
    	display:block;
    	text-indent:-999em;
    	width:48px;
    	height:48px;
    	overflow:hidden;
    	background-image: url(miniat1.png);
    }
     

    ¿Podéis darme alguna instrucción, acompañada de una collejilla si hace falta?, pero no veo cómo hacerlo…

    ¡Gracias por adelantado!

  63.  Yolanda Torre dice:

    Deciros que he tenido suerte y he conseguido la ayuda de un amigo que controla mucho y lo ha resuelto.

    Si queréis saber cómo os lo envio.

    Un saludo.

  64.  Saúl González Fernández dice:

    @Yolanda: Disculpa que hayamos tardado en contestar, pero el volumen de trabajo actual no nos permite atender el blog tanto como querríamos.

    Como bien indicas, los cambios del código que señalas en tu primer comentario se deben hacer en el archivo DP.js.

    En cuanto a asignar las miniaturas, con el selector #contador li a estás asignando la imagen miniat1.png a todos los vínculos del contador. Para asignar imágenes distintas tendrías que añadir estas declaraciones:

    
    #con1 li a{  background: url(miniat1.png) 0 0 no-repeat; }
    #con2 li a{  background: url(miniat2.png) 0 0 no-repeat; }
    …
    #conN li a{  background: url(miniatN.png) 0 0 no-repeat; }
     
  65.  pablo dice:

    Hola. Muchas gracias por el carrusel, pero he intentado colocar el carrusel tres veces, una a continuación de otra, en la misma pagina pero solo me aplica el efecto al primero y los otros dos me los deja como si fuera una lista de imagenes.

    Un saludo.

  66.  Saúl González Fernández dice:

    @pablo: Como comentamos en la entrada, el uso del script es muy específico: no está pensado para que aparezca más de uno por página.

    Podrías convertir idD y nID en una matriz cuyos índices sean los id de los elementos originales y sus valores los nuevos id que les asignas. Luego en la funcion inicio tendrías que incluir un for que recorriera la matriz y aplicara las sentencias a cada elemento.

  67.  pablo dice:

    OK, muchas gracias por la respuesta.

  68.  Jesús dice:

    Hola. Muy buena solución. Me gustaría poder usarlo en una web que estoy haciendo. De hecho, en local funciona perfectamente, pero a la hora de llevarlo a servidor no funciona. Soy novato en temas de programación, js y demás. Estaría muy agradecido si me indicárais cuál puede ser mi error. Todos los archivos de local coinciden en ubicación y nombre con los del servidor, pero…

    Un saludo y muchas gracias.

  69.  Saúl González Fernández dice:

    @Jesús: ¿Puedes explicarnos con un poco más de detalle cuál es el problema? ¿El script parece funcionar, pero no se ven las imágenes? ¿No funciona en absoluto? ¿Puedes darnos una URL en la que verlo?

  70.  Jesús dice:

    El problema se corresponde con lo que describes en la entrada: «las imágenes aparecen simplemente una debajo de otra cuando el cliente no dispone de soporte para JavaScript», pero todos los ejemplos vuestros e incluso de alguno que lo ha publicado aquí, se ven correctamente . Puedes verlo en http://www.correctoronline.com/pruebas. Sólo se ha modificado el CSS, nada del script.

    Un saludo y muchas gracias de antemano.

    Cuando tenga la web lista prometo enlace a vuestro sitio.

  71.  Saúl González Fernández dice:

    @Jesús: Creemos que el problema es que en la línea <script type="text/javascript" src="js/DP.js"></script> no estás apuntando correctamente a la ubicación del script; http://www.correctoronline.com/pruebas/js/DP.js nos devuelve la página del 404.

  72.  Jesús dice:

    DP era dp. Muchas gracias por dar con el quid. Los errores tontos son los que más tiempo hacen perder. Disculpad haberos hecho perder el vuestro.

    Un saludo y muchas gracias.

  73.  Saúl González Fernández dice:

    @Jesús: Tranquilo, precisamente como nosotros los hemos cometido muchas veces, identificamos enseguida esos errores.

  74.  José Díaz dice:

    Saúl, solo darte las gracias por tu gran aporte y por la atención que prestas a todo el que te pregunta, está excelente el carrusel. Saludos.

  75.  Juan Nájera dice:

    Disculpa, ¿cómo puedo mandar llamar varias funciones del .js que hiciste? Me refiero a que deseo tener dos sliders pero claro funcionan con el onload. ¿Cómo puedo cargar para que se ejecuten y funcionen los dos slider con ese código?

  76.  Saúl González Fernández dice:

    @Juan: un poco más arriba respondemos a eso.

  77.  Martin aguilar dice:

    Hola. Muy bueno el aporte, yo utilicé el script en una web que estoy creando. En Chrome y Firefox se ve perfecto y las imágenes se desplazan, pero en Explorer queda la imagen fija y no avanza. Por favor, ¿me podrían ayudar con esto?

    Gracias de antemano.

  78.  Saúl González Fernández dice:

    @Martin: En principio el script funciona en Explorer desde la versión 8 en adelante.

  79.  lily dice:

    ¿Cómo puedo hacer para centrar las imágenes dentro de una tabla?

  80.  Saúl González Fernández dice:

    @lily: No emplees una tabla, al contenedor de la lista aplícale un margin: 0 auto;.

  81.  miguel dice:

    ¡Buenas! Estupendo aporte.

    Estoy intentando utilizarlo para una web personal y me gustaría incluir los recuadros de contador dentro de las imágenes grandes.

    Lo tengo colocado en la posición que deseo… peeeeeeeero me aparecen tras la imagen. He probado con z-index pero no consigo que se vea, sé donde están ubicadas porque cuando hace la transición las veo entre pase de diapo y diapo.

    También le he quitado el sombreado.

    ¿Alguien puede decirme cómo hacer visibles y operativos los botones del contador?

    Muchas gracias de antemano, paso la css a continuación.

       
    *{padding:0;margin:0;border:0;}
    body{color:#FFF;background:#333 url(fondo.png) left top repeat-x;}
    #diapos-on{border:10px solid #FBFBFB; width:700px;height:320px;margin:5em auto 0;position:relative;}
    #diapos-on li{position:absolute;top:0;left:0;width:700px;height:320px;list-style:none;}
    #contador{width:700px; margin-left:300px; margin-top:-40px;}
    #contador li{float:left;width:20px;height:20px;margin-right:5px;list-style:none;}
    #contador li a{display:block;text-indent:-999em;background:#F9D8E3;width:20px;height:20px;overflow:hidden;}
    #contador li a:focus{outline:1px solid #F9D8E3;}
    #contador li.actual a{background:#E6658E;}
    
  82.  Saúl González Fernández dice:

    @Miguel: lo que ocurre es que para que el z-index se aplique correctamente debes crear un nuevo contexto de apilamiento. Prueba esto:

    
    #contador{width:700px; margin-left:300px; margin-top:-40px; position:relative; z-index:99;}
     
  83.  migueleos dice:

    Soy un diseñador gráfico trabajando a un nivel de principiante en la programación. Agradezco la aportación de tus conocimientos amigo.
    Seguiré trabajando con los códigos que nos has dejado.

  84.  Diego Ernesto Vitteri Murga dice:

    Luego de algunos problemillas (especialmente las instrucciones para el CSS que finalmente encontré viendo el código de uno de los ejemplos), todo quedó funcionando perfectamente y lo adapté sin problemas a mis necesidades, muchísimas gracias.

    Tengo una consulta extra, quiero que cada imagen me lleve a un link diferente, en realidad a diferentes anclas dentro de una misma página, pero si bien el link funciona perfectamente llevándome a la página correcta… el única ancla que funciona es la última, ninguna de las anteriores carga, todos los gráficos aparecen con un sólo link, este es el código que usé:

      <a href="noticias.html#noticia1"></a>
      <a href="noticias.html#noticia2"></a>
      <a href="noticias.html#noticia3"></a>
      <a href="noticias.html#noticia4"></a>
      <a href="noticias.html#noticia5"></a>
      <a href="noticias.html#noticia6"></a>
      <a href="noticias.html#noticia7"></a>
    

    Les agradecería mucho me ayudaran con esto.

  85.  Saúl González Fernández dice:

    @Diego Ernesto: Ese problema lo corregimos en una versión distinta del script. Échale un vistazo.

  86.  luis dice:

    Estimados tengo un problema.
    Al momento de ejecutar el script me sale este error:

    ReferenceError: Dp is not defined
    window.onload = Dp.inicio;

    Adicionalmente las imágenes se presentan en forma de lista, el ejemplo lo visualizo sin ningún problema.
    Gracias.

  87.  luis dice:

    Estimados,
    ¿debo tener instalado jQuery para que funcione?

  88.  Saúl González Fernández dice:

    @Luis: No, no tienes que tener instalado jQuery, el script no depende de ninguna librería. Lo único que se me ocurre es que la línea window.onload = DP.inicio; se esté ejecutando antes de la carga del script, o que estés ejecutando Dp.inicio en lugar de DP.inicio (recuerda que JavaScript es sensible al caso).

  89.  Claudia dice:

    Hola:
    Tengo un banner hecho con jquery. La cuestión es que el banner pasa demasiado rápido de una imagen a la otra, lo que quiero hacer es volverlo más lento, es decir que las imágenes pasen de forma más lenta entre una y otra. ¿Que tengo que hacer?

    Este es el Script que tengo del banner:

     
      $(window).load(function() {
        $('#slider').nivoSlider();
      });
     

    Gracias

  90.  Saúl González Fernández dice:

    @Claudia: Revisando el .js original del plugin en Github, veo que hay un parámetro configurable que es pauseTime, en el que puedes indicar el intervalo de tiempo entre transiciones en milisegundos.

    Prueba esto:

    
      $(window).load(function() {
        $('#slider').nivoSlider({pauseTime:7000});
      });
     

    En teoría esto debería hacer que cada imagen se mantenga 7 segundos.

  91.  claudia dice:

    Muchas gracias, me funcionó a la perfeccción.

  92.  Alex dice:

    Excelente tutorial, muy bien explicado y sencillo de entender, de lo mejor.
    Me ha funcionado perfectamente, pero tengo un duda:
    ¿Cómo se podría hacer para que las imágenes se visualizaran de manera aleatoria?
    ¡Muchas gracias!

  93.  Saúl González Fernández dice:

    @Alex: Prueba sustituir la funcion fun por ésta:

    
    fun: function(){
      var i = 100;
      while(DP.sD==DP.dA){
        DP.sD = Math.round(Math.random()*(DP.tD-1)+1);
      }
      DP.intv = setInterval(function(){
        i = i-5;
        if(i>=0){
          DP.op(DP.ds[DP.dA],i);
          DP.op(DP.ds[DP.sD],(100-i));
        } else {
          DP.ac('');
          DP.dA = DP.sD;
          DP.ac(DP.clC);
          clearInterval(DP.intv);
          if(DP.anim){DP.lnz = setTimeout(DP.fun,DP.t);}
        }
      },50);
    }
     
  94.  Alex dice:

    Muchísimas gracias, ¡funciona! Lo único, ya para rizar el rizo, la primera imagen que aparece siempre es la misma, que es la primera de la lista.

    ¿Es posible que también la primera aparezca de manera aleatoria?

    Gracias.

  95.  Saúl González Fernández dice:

    @Alex: Sí, sustituye esta línea:

    
    DP.op(DP.ds[0],100);
     

    por estas:

    
    DP.dA = Math.round(Math.random()*(DP.tD-1)+1);
    DP.op(DP.ds[DP.dA],100);
     
  96.  Alex dice:

    ¡Muy bien! Ahora la primera sale aleatoria.
    De todas formas ahora siempre sale la segunda la primera de la lista, jejeje.
    Muchas gracias, fabuloso blog el vuestro.

  97.  Amparo dice:

    Hola, para mi blog de wordpress estoy usando un tema que trae un carrusel incluido. Mi problema es que al finalizar la presentación de las diapositivas la última siempre sale vacía. Si pongo 3 imagenes me salen 4 cajitas, si pongo 5, aparecen 6 y la última siempre vacía. He probado a instalar otros temas similares y en todos me sucede lo mismo. Qué puede ser? Si el error no está en el tema dónde busco? No sé programación ni diseño. Lo cierto es que en algún momento si que funcionó. Ayuda por favor!!

    Un saludo y gracias

  98.  Amparo dice:

    Ya lo solucioné. Era un conflicto que tenía con un plugin. Llevaba semanas intentando solucionarlo. De todos modos muchas gracias.



Artículos relacionados

 ScrollTo en menos de 2Kb

ScrollTo en menos de 2Kb

Siguiendo con nuestra iniciativa de replicar efectos de animación populares de JavaScript en menos de 2Kb, creamos un ScrollTo que no depende de ninguna librería. El efecto Habrá visto en muchos sitios web —sobre todo en los que consisten en una única página— un efecto que consiste en que al ha

Efectos javascript

Un acordeón fallido con CSS3 Creamos una interfaz de acordeón con un híbrido de transiciones de CSS3 y JavaScript. Carrusel con desplazamiento horizontal, en menos de 2… en lo menos que hemos podido Programamos un carrusel de contenidos con desplazamiento horizontal, flexible y casi en menos de 2Kb. ScrollTo,