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 hacer clic en un vínculo interno, el documento se desplaza progresivamente hacia su destino, en lugar de simplemente «saltar» a él. Bien, pues hemos querido crear un script que duplique este comportamiento, para quien no quiera recurrir a un plugin de jQuery o MooTools.

Nuestros requisitos, los de siempre:

  • El script no debe depender de ninguna librería de JavaScript.
  • Debe degradarse de manera elegante.
  • Debe pesar menos de 2Kb sin minimizar.

El script

Antes de nada, y para los impacientes, un ejemplo funcional. Y ahora el código:


var SC = {
  mov : [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1],
  url : (document.location.href.split('#'))[0],
  $ : function(id){var elem = document.getElementById(id);return elem;},
  ev : function(x,y,z){(document.addEventListener) ? x.addEventListener(y,z,false) : x.attachEvent('on'+y,z);}, 
  pD : function(x){(x.preventDefault) ? x.preventDefault() : x.returnValue = false;},
  sc : function(e){
    SC.pD(e);
    e.target ? e = e.target : e = e.srcElement;
    e.toString().match('#') ? e = e : e = e.parentNode;
    var o = 0,ID = (e.toString().split('#'))[1],y = SC.$(ID),x = 0,dir = 0,dis = 0,inc = 0;
    window.pageYOffset ? o = window.pageYOffset : o = document.documentElement.scrollTop;
    while(y){x += y.offsetTop;y = y.offsetParent;}
    (x>o) ? dir = 1 : dir = -1;
    dis = Math.abs(x-o);
    for(var i=1;i<SC.mov.length;i++){
      inc = Math.round((dir*(dis*(SC.mov[i]/100))));
      o += inc;
      window.scrollTo(0,o);
    }
    window.scrollTo(0,x);
    document.location.href = SC.url+'#'+ID;
  },
  inicio : function(){
    var vs = document.getElementsByTagName('a');
    for(var i=0;i<vs.length;i++){
      if(vs[i].href.match(SC.url+'#')){
        SC.ev(vs[i],'click',SC.sc);
      }
    }
  }
}
	

Vamos a explicar someramente algunos de los puntos del código:

  • mov es una variable que describe el movimiento de la animación. Más abajo explicaremos para qué sirve.
  • $, ev y pD son funciones de apoyo, la primera simplifica la sintaxis de getElementById, y las otras dos dan cuenta de las diferencias entre Explorer y otros navegadores en la asignación de escuchas de eventos y la prevención de comportamientos por defecto, respectivamente.
  • e.target ? e = e.target : e = e.srcElement; identifica el vínculo activado. srcElement es la propiedad de Explorer.
  • Con la línea e.toString().match('#') ? e = e : e = e.parentNode; capturamos el vínculo que se ha activado, y del que sacaremos el identificador del destino. Añadimos el e = e.parentNode, porque puede ser que el vínculo tenga dentro otro elemento —por ejemplo una imagen—, que es el que devolvería la línea anterior.
  • window.pageYOffset ? o = window.pageYOffset : o = document.documentElement.scrollTop; nos indica la posición actual del scroll del documento, que almacenamos en o y que tomamos como el punto en el que comenzará la animación. document.documentElement.scrollTop es el código para Explorer.
  • while(y){x += y.offsetTop;y = y.offsetParent;} calcula la distancia en píxeles desde el inicio del documento hasta el elemento de destino, almacenado en y.
  • (x>o) ? dir = 1 : dir = -1; simplemente nos indica si el desplazamiento será ascendente o descendente.
  • dis = Math.abs(x-o); almacena la distancia entre ambos puntos.
  • for(var i=1;i<SC.mov.length… es el bucle que crea el movimiento. Cada vuelta calcula la cantidad de píxeles que se debe mover el scroll según el patrón de mov.
  • Tras el bucle, por medio de window.scrollTo(0,x); asignamos explicitamente la nueva posición del documento, para corregir un posible desfase en píxeles debido al redondeo de las distancias en aquel.
  • Con document.location.href = SC.url+'#'+ID; actualizamos el URL de la página.
  • La función inicio simplemente revisa el árbol del documento en busca de los vínculos a los que asignar la animación.

Ahora, ¿qué es exactamente mov? Es una variable que describe de forma genérica el patrón del movimiento de la animación: establece tanto el número de «fotogramas» en los que se realizará el desplazamiento, como la relación que existe entre ellos. Por ejemplo, mov : [10,10,10,10,10,10,10,10,10,10] daría lugar a una animación de cinco «saltos» de la misma distancia cada uno, con lo que su movimiento sería uniforme. En el valor que le hemos asignado por defecto, la animación consta de 19 fotogramas, y es más lenta al principio y al final para darle cierto efecto de aceleración-frenado que crea un movimiento más natural. Un patrón como [10,9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1] daría un moviento consistente sólo en la parte de frenado, y en orden inverso sólo de aceleración —nótese que la suma final siempre tiene que ser 100, puesto que definimos porcentajes de la distancia total del desplazamiento—. Y ya experimentando, [10,8,6,4,2,4,6,8,10,8,6,4,2,4,6,8,4] crearía un movimiento «ondulante». Importante: cuantos más fotogramas se incluyan, más fluido será el movimiento, aunque también se consumirán más recursos del motor de JavaScript del cliente, por lo que hay que hacerlo con moderación.

Un 93,2% de españoles reconoce tener problemas con su WiFi

Un 93,2% de españoles reconoce tener problemas con su WiFi

– La mayoría de los usuarios de Internet de nuestro país ha sufrido alguna vez problemas relacionados con el WiFi, según un estudio realizado por devolo en julio de 2021 que refleja el estado y la percepción de los españoles respecto a su conexión a Internet en el hogar. El objetivo de dicho estud

 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

Responsive images sin JavaScript ni PHP

Responsive images sin JavaScript ni PHP

A día de hoy, responsive design arroja 77 millones de resultados aproximadamente de Google, pero a pesar de las virtudes y la relativa facilidad con la que crear un diseño adaptativo, hay un bestia negra que plantea un problema: las imágenes. Pensando en ello hemos hecho un pequeño experimento. El problema reside en

Destacar y atenuar elementos simultáneamente con CSS3

Destacar y atenuar elementos simultáneamente con CSS3

En algún blog nos hemos encontrado con un efecto my sutil, pero que nos ha parecido muy elegante: ver una lista de elementos como comentarios, tweets o entradas relacionadas, que al pasar el ratón por encima reaccionan oscureciendo el ítem que recibe el :hover, y atenuando los demás. En muchos casos se trata de un efecto

MapBox: una alternativa al mapa de Google

MapBox: una alternativa al mapa de Google

Llevábamos unas semana buscando un rato libre para probar MapBox, y por fin lo hemos encontrado: El servicio nos permite generar un mapa con la misma funcionalidad que nos ofrece Google Maps, pero con la interesante adición de poder alterar aspectos como la paleta de colores, iconos y demás, de manera que se pueda ajustar m&

Clientes

Nos valoran 9,3 sobre 10 La satisfacción de nuestros clientes es nuestro objetivo, y su evaluación es lo más provechoso que nos aportan. Por ello, cuando terminamos un proyecto les pedimos que puntúen una serie de aspectos de nuestro trabajo que pueden servir de referencia para nuestros futuros clientes. Como con

Outline y los bordes redondeados

La propiedad outline dibuja alrededor de un elemento una línea a modo de marco que puede emplearse como un segundo borde a efectos de estilo. Sin embargo, esta línea no sigue el contorno de dicho elemento si a éste se le asigna un radio de borde para redondear las esquinas. En esta entrada muestro un par de soluciones a este pe

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 e

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,

Menús desplegables animados con CSS3

Los menús desplegables son una interfaz de navegación muy común. Hasta ahora con CSS podíamos hacer que los vínculos de las subsecciones aparecieran sin necesidad de JavaScript, pero si queríamos hacer que el efecto de dicha aparición fuera progresivo, no nos quedaba más opción que prog

Contrato diseño web

Contrato de diseño y desarrollo de sitio web INTERVIENEN   De una parte, D. [el nombre de nuestro representante], mayor de edad ycon N.I.F. 53022319-M, en calidad de [cargo en nuestra empresa] de DigitalIcon, Servicios Informáticos, S.L. (en adelante DIGITAL ICON), con C.I.F. B-84622927 y con domicilio social en Plaza Mayor