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

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:

  • El script no debe depender de ninguna librería de JavaScript.
  • Debe degradarse de manera elegante.
  • Debe pesar menos de 2Kb sin minimizar (y sólo porque pensamos que en 1Kb es del todo imposible).

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:

  • t: Es el tiempo de exposición de cada diapositiva entre transición y transición.
  • idD: El id de la lista que incluye las diapositivas.
  • nID: El nuevo id que se asigna a esa misma lista. Un poco más abajo discutimos su sentido.
  • idC: El id del indicador de progreso al pie de las diapositivas, que permite aplicarle un estilo específico.
  • clC: La clase asignada al número actual de diapositiva en el mismo.

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:

  • Primero, el punto 2.1 dice que toda funcionalidad que se proporciona en la página debe ser accesible por medio del teclado. La navegación que proporciona el indicador de progreso debajo del carrusel consiste en una lista de enlaces comunes y corrientes, por lo que se pueden navegar por medio de la tecla Tab.
  • Segundo, el punto 2.2.2 indica que para todo contenido que se desplace y que se inicie de manera automática se debe proporcionar un mecanismo que permita pausarlo, detenerlo u ocultarlo. Hemos elegido la segunda opción, y el carrusel se detiene en cuanto el usuario decide navegarlo manualmente.

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.

Etiquetas: , , .

Esta entrada se publicó el 13 de Mayo de 2010 a las 9:33, y se archivó en JavaScript. Autor: Saúl González. Puede seguir los comentarios de esta entrada a través de RSS 2.0. Puede dejar un comentario o hacer un trackback desde su propio sitio.

¿Algún comentario?

© Digital Icon, S.L., 2006–2010 | Gracias a la generosidad de WordPress | Diseño del tema: constructoweb