Añadir efectos de desplazamiento vertical en la misma página

Cómo animar enlaces internos con jQuery (con y sin WordPress)

Al utilizar enlaces internos con anclas en HTML, podemos añadir algunos efectos para que, en vez de saltar directamente, el navegador se deslice suavemente hasta el destino en la misma página utilizando una animación. No solo es más agradable, sinó que ayuda a entender al usuario que en vez de cambiar de página, le hemos llevado a un punto interno.

Este efecto se puede conseguir muy fácilmente añadiendo algo de Javascript al proceso. jQuery, la librería más utilizada actualmente para conseguir estas animaciones, nos permite añadir este tipo de efectos fácilmente y con muy poco código. Además, al tratarse de Javascript, funcionará sin problema en cualquier navegador, tanto Firefox, Google Chrome, Safari como Internet Explorer y sus versiones antiguas.

En el siguiente ejemplo se puede ver lo que queremos conseguir: al pulsar sobre los links del menú principal (las letras: A, B, C…) todo el contenido se desplaza suavemente hasta el destino, y al pulsar sobre el botón “Subir”, volvemos arriba utilizando el mismo efecto de scroll vertical animado:

Demo: http://jsfiddle.net/fD8zJ/5/

1. Marcamos los enlaces y destinos

Antes de añadir efectos es importante preparar los enlaces para que funcionen sin necesidad de Javascript. Esto ya lo vimos al hablar de los enlaces anclados.

Cada botón o enlace tiene que apuntar a un destino interno añadiendo el símbolo de la almohadilla o numeral (#) delante del nombre del identificador. Después, en el destino de ese enlace tenemos que añadir el atributo “name” o “id”. En el ejemplo anterior: <h2 id="a">A</h2>

Una vez hecho esto deberíamos probar los enlaces, para asegurarnos de que funcionan normalmente, sin ningún tipo de animación.

2. Cargamos jQuery

Después, el siguiente paso será ver si tenemos la librería de jQuery cargada, para poder trabajar con sus funciones y animaciones. Si no es así, lo primero que habrá que hacer es añadir jQuery al final de la página (antes del cierre de <body>), o bien en la cabecera (<head>), según lo que convenga en cada caso (WordPress, por ejemplo, añade jQuery en la cabecera).

A ser posible, conviene que enlacemos estos scripts al final de la página, ya que las etiquetas <script> detienen el renderizado de la página hasta que el código se ha cargado completamente. En otras palabras, cuando alguien visita nuestra web, todo el proceso de montaje de la página (HTML, CSS, Javascript) se para hasta que se han descargado las hojas de Javascript que hayamos incluido.

Una solución rápida puede ser añadir la librería de jQuery comprimida alojada directamente en los CDNs de Google:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

O, si por alguna razón preferimos no utilizar servicios de Google, podemos cargar las librerías alojadas en cdnjs.com:

//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js

jQuery en WordPress

Si la web está montada sobre WordPress, el paso anterior puede que no sea necesario, ya que este gestor de contenidos incorpora una copia de jQuery entre sus archivos, aunque por defecto WordPress no lo carga automáticamente, así que tendremos que activarlo de manera manual.

Lo mejor de todas formas, para no equivocarnos, es mirar directamente el código de la página y ver si jQuery ya está presente (lo más probable, ya que muchos plugins y temas lo utilizan). Si no es así, podemos cargarlo añadiendo esta función en el archivo functions.php del tema que tengamos activo:

function mitema_scripts() {
	// Cargamos la copia de Jquery incluida con WordPress
	wp_enqueue_script( 'jquery' );
}
add_action( 'wp_enqueue_scripts', 'mitema_scripts' );

3. Añadimos los efectos con jQuery

Ahora que ya tenemos todo lo necesario, es hora de empezar a añadir el comportamiento y las animaciones con jQuery:

<script>
jQuery(document).ready(function(){
    $('h2').append('<a href="#top" class="gototop">Subir</a>');
    linkInterno = $('a[href^="#"]');
    linkInterno.on('click',function(e) {
	e.preventDefault();
	var href = $(this).attr('href');
	$('html, body').animate({ scrollTop : $( href ).offset().top }, 'slow');
	});
});
</script>
  • Linea 2: añadimos nuestras instrucciones una vez finalizada la carga de la página, cuando el DOM (Document Object Model) está listo. Si estamos utilizando WordPress, en vez de utilizar el símbolo de jQuery (el dolar) tendremos que utilizar la palabra “jQuery” y (opcionalmente) pasar el símbolo dentro de la función, así: jQuery(document).ready(function($)… Esto se debe a que WordPress utiliza un modo especial para evitar conflictos llamado No-Conflict. Si ves que el código no funciona y te aparece el error “TypeError: $ is not a function“, el problema se soluciona haciendo el cambio comentado en esta linea.
  • Linea 3: Añadimos al lado de cada título (h2) un botón para volver arriba, que también utilizará el desplazamiento suave vertical.
  • Linea 4: Aquí tendremos que especificar qué enlaces queremos animar. En el ejemplo hemos guardado en la variable “linkInterno” todos los links que empiecen con el símbolo de la almohadilla (#, es decir, enlaces internos), para que no haya conflictos con otros links que pueda haber en la misma página.
  • Linea 5: Añadimos el evento click() a los enlaces seleccionados en la linea anterior. Cada vez que uno de los links especificados reciba un click de ratón se activará esta función.
  • Linea 6: Anulamos el comportamiento por defecto del enlace con preventDefault(), evitando así que el símbolo de la almohadilla junto con el nombre del ancla aparezcan en la URL al pulsar sobre él.
  • Linea 7: Guardamos en otra variable el contenido del atributo “href” de cada uno de los enlaces, para hacerlo más dinámico y no tener que especificar cada uno por separado.
  • Linea 8: Añadimos la función “animate” de jQuery a las etiquetas HTML y BODY (para que funcione en todos los navegadores). Si queremos ir un paso más allá, podemos cachear esta consulta en una variable para que no se ejecute cada vez que pulsamos un enlace. Después, definimos las opciones de velocidad, en milisegundos o con palabras clave: slow (lento, 600 ms) o fast (rápido, 200 ms).

Entrada relacionada: Mostrar y ocultar elementos de una web con jQuery Toogle. Ejemplos prácticos

4. Mejorando las animaciones con efectos de suavizado

Para mejorar la animación de los enlaces podemos añadir otros efectos de suavizado, impulso y frenado (easing) para que el desplazamiento sea más natural, en lugar de lineal. Esto dará un mejor aspecto al efecto final de desplazamiento vertical, aunque es totalmente opcional.

Para ello podemos añadir el plugin jQuery Easing de varias maneras:

1. Directamente en la cabecera o pie de página (siempre después de jQuery):

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>

2. O bien, si estamos trabajando con WordPress, adjuntando el código en la misma función que hemos creado anteriormente con “wp_enqueue_script“:

function mitema_scripts() {
	// Cargamos la copia de Jquery incluida con WordPress
	wp_enqueue_script( 'jquery' );

	// Cargamos el plugin de animaciones de jQuery Easing en el footer
	wp_enqueue_script( 'jq-easing', 'https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js', array('jquery'), null, true );
}
add_action( 'wp_enqueue_scripts', 'mitema_scripts' );

Ahora, para poder aprovechar las nuevas animaciones, tenemos que añadir el nombre del efecto que queramos utilizar después de la velocidad. Así:

<script>
$(document).ready(function(){
    $('h2').append('<a href="#top" class="gototop">Subir</a>');
    linkInterno = $('a[href^="#"]');
    linkInterno.on('click',function(e) {
	e.preventDefault();
	var href = $(this).attr('href');
	$('html, body').animate({ scrollTop : $( href ).offset().top }, 'slow', 'easeInOutExpo');
	});
});
</script>

La única diferencia con la versión anterior de este código es que ahora le hemos añadido el efecto “easeInOutExpo” (en la linea 8) después de la velocidad (slow).

Este plugin de suavizado nos permite utilizar bastantes variaciones, según el tipo de animación que estemos buscando (suavizado inicial, final, impulsos, retrocesos, etc.): easeInOutQuad, easeInOutCubic, easeInOutSine, easeInOutBack, easeInOutBounce…

Demo: http://jsfiddle.net/fD8zJ/5/

Demasiado complicado, necesito un plugin

Para los que necesitan una solución rápida y fácil de integrar, además de tutoriales existen bastantes plugins que ayudan a añadir animaciones de desplazamiento a los enlaces internos. Por ejemplo:

Comentarios

  1. Miquel

    Excelente! Lo más comprensible que he encontrado para los que sólo sabemos trabajar con CMS.
    Pero me quedo parado aquí:
    “Para ello podemos añadir el plugin jQuery Easing de varias maneras:
    1. Directamente en la cabecera o pie de página (siempre después de jQuery, por supuesto): ”

    Aquí falta algo, porque pasa directamente a dar el código para WP, sin especificar el plugin.
    Gracias!

  2. Miquel

    Especifico: Hasta aquí el desplazamiento ralentizado funciona perfectamente.
    Me quedo parado al querer añadir los efectos Easing.

  3. Daniel

    Hola Miquel.
    Tienes razón, faltaba añadir el link al plugin de jQuery Easing y la linea con el script. Ya está arreglado. Muchas gracias por avisar!

  4. Raul

    por mucho que lo intento no logro hacerlo … he provado muchas formas y he retocado el codigo para adaptarlo pero tampoco, no tengo forma de hacer esta funcion….

    no sé como hacerlo… estoy trabajando con prestashop y quizas alguna cosa este entorpeciendo el codigo.

    podrias ayudarme?

  5. Daniel

    Si no funciona, lo primero de todo conviene mirar en la consola del inspector, a ver si hay algún error de Javascript (conflictos, funciones no definidas, etc.)

    También puedes crear una versión reducida aparte, por ejemplo en http://jsfiddle.net/ para ver dónde falla.

    Se trata de eliminar uno a uno los posibles problemas: funciona jQuery? Deja de funcionar con alguna versión en concreto? Funciona el link sin animación? Funciona sin efectos? …

  6. Alex

    Hola, muy padre!

  7. Arthurok

    Muy muy bueno, por fin lo comprendí y logre hacer gracias a la explicación tan detallada, felicitaciones!!!

  8. Jose

    Hola, me sirvió bastante tu tutorial, estoy bastante agradecido. Pero tengo una duda mayor: lo que pasa es que tengo un scrollup (botón que aparece en cierto punto de la pagina para volver al inicio con transición) y lo que quiero lograr es poder no volver al inicio, si no que a un cierto punto de la pagina.
    http://markgoodyear.com/labs/scrollup/?theme=image
    ese es el script que te digo. Estaría bastante agradecido si me pudieses ayudar

  9. Antonio

    Hola estoy intentando aplicar esto en wordpress sustituyendo los “$” por “jQuery” pero la consola de JavaScript me dice esto:

    TypeError: jQuery(…).offset(…) is undefined

    El error que aparece en la consola me lleva a esta linea:

    jQuery(‘html, body’).animate({ scrollTop : jQuery( href ).offset().top }, ‘slow’);

  10. Emer

    Hola, soy novato en todo este tema y agradezco estos epacios para ayudar a los que comenzamos en esto.
    Estoy desarrollando un sitio a partir de wordpress pero no logro hacer que funcione esta animación del scroll. No se si se debe a la plantilla en la que estoy trabajando o eso no tiene nada que ver.

    No entiendo en donde puedo visualizar si jQuery ya esta presente, aunque como bien dice, supongo lo está por los plugins que ya estan en uso. Ahora suponiendo que no esté cargado he agregado el código citado sustituyendo mitema_scripts por el nombre del tema que uso_scripts en la primer linea del functions.php del tema en uso, pero al hacerlo la web deja de funcionar por completo arrojando este error en la consola de javascript: Failed to load resource: the server responded with a status of 500 (Internal Server Error). Lo he intentado al final del documento obteniendo el mismo error.
    Pense que era porque ya estaba activo jQuery y solo necesitaba agregar

    jQuery(document).ready(function(){
        $('h2').append('<a href="#top" rel="nofollow">Subir</a>');
        linkInterno = $('a[href^="#"]');
        linkInterno.on('click',function(e) {
        e.preventDefault();
        var href = $(this).attr('href');
        $('html, body').animate({ scrollTop : $( href ).offset().top }, 'slow');
        });
    });
    

    para generar el efecto, lo he intentado al principio del documento function.php y al final del mismo pero no consigo nada solo el mismo error. Agradezco la paciencia y el tiempo dedicado.

  11. Daniel

    Hola Emer.
    La manera más fácil de comprobar si el tema de WordPress que utilizas incluye jQuery es mirando directamente el código de la web con el navegador y buscar la palabra “jquery”.

    Por otro lado, si te sale un error del servidor (error 500) tiene que ser por algo relacionado con PHP (en este caso), no por nada relacionado con Javascript. Comprueba que no haya ningún error al copiar el código que has añadido en functions.php.

    Cuando consigas que desaparezcan los errores del servidor, mira en la consola del navegador para ver si hay algún error o aviso de Javascript que te dé alguna pista sobre el problema.

  12. Sr. ilustre

    Funcionalidad totalmente necesaria para dispositivos moviles, donde la pantalla es pequeña y si no programas tu mismo el desplazamiento el usuario ni se entera. Buen aporte, gracias.

  13. Biechevarria

    Hola.
    Tengo practicamente desarrollada una web (toda en una misma pagina).
    Para moverme uso ancalas/id. Al pinchar en los item de menu los cuales me llevan al contenido, resulta que aparece el nombre del ID/ANCLA correspondiente.
    Hay alguna forma de quitar estos id o anclas de la URL???
    Muchas gracias y un abrazo.

  14. Mike

    Excelente. Necesitaba un simple Slider para trabajar con Anclajes y lo conseguí sin esfuerzos. Saludos cordiales.

  15. Carlos

    Perfecto, gracias

Y tú qué opinas?

Las URLs se convertirán en enlaces automáticamente. Tu dirección de email no se publicará ni se utilizará para enviar ningún tipo de información. Los mensajes que no aporten nada al tema que se trata en esta entrada se borrarán. Las imágenes que aparecen al lado de cada autor utilizan el servicio de Gravatar. Recuerda que puedes usar etiquetas HTML como <a href>, <code>, <em> o <strong> en los comentarios.

(necesario)

(opcional)