Ejemplos jQuery

Desplazamiento animado en anclas de enlaces con jQuery

1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (3 votos, promedio: 5,00 de 5)
Cargando...

Estaba buscando para un proyecto en el que estoy trabajando la manera de hacer desplazamientos dentro de la página de una forma menos brusca a la que brinda el html. Aquí la solución.

Estaba buscando para un proyecto en el que estoy trabajando la manera de hacer desplazamientos dentro de la página de una forma menos brusca a la que brinda el html.

Como sabréis, se pueden crear enlaces que apunten a zonas concretas dentro de la misma página con el elemento href=#. Esto es útil por ejemplo, cuando la página tiene mucho contenido y por tanto mucho scroll vertical, para poner ayudas al usuario y llevarle a zonas importanes de la página con los típicos enlaces de “saltar a contenido”.

Esto se puede hacer con HTML básico de esta manera:

Creas el enlace ancla que va a llevar a otra parte de la página:

<a href="#ancla">Ancla</a>

Creas el id para la zona de la página a donde quieres que lleve el ancla:

<div id="ancla">
... contenido
</div>

El funcionamiento es perfecto, lo que no me gusta es el modo de hacerlo que tiene el HTML, ya que provoca un salto brusco.

Bueno, para hacerlo de forma suavizada, tal y como se muestra en este ejemplo, se consigue poniendo este código JavaScript (jQuery) en el head de tu web o en un archivo externo .js:

$(function(){

     $('a[href*=#]').click(function() {

     if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
         && location.hostname == this.hostname) {

             var $target = $(this.hash);

             $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');

             if ($target.length) {

                 var targetOffset = $target.offset().top;

                 $('html,body').animate({scrollTop: targetOffset}, 1000);

                 return false;

            }

       }

   });

});

Voilá, con este pequeño código en jQuery nada intrusivo se consigue un bonito efecto para tus desplazamientos de página.

Particularmente pienso que este pequeño detalle ayuda a mejorar la usabilidad de este tipo de enlaces, que son poco usables por concepto, precisamente por cosas como las que el propio Nielsen publicó hace años sobre el tema:

Según Nielsen, hay que evitar el uso de enlaces de ancla dentro de las páginas por la sencilla razón de que el usuario tiene un modelo mental bien definido acerca del comportamiento de los enlaces, de forma que cuando pincha en un link espera ser dirigido a una página web distinta de la que está visitando. Los enlaces de ancla violan ese modelo mental al enlazar a zonas dentro de una misma página, lo que puede confundir al usuario.

Con este efecto en jQuery queda más clara la acción del enlace, puesto que en todo momento ves lo que está pasando al notar el desplazamiento, mientras que con html el cambio es tan brusco que parece que te has teletransportado a otro sitio (con perdón de la forma de explicarlo).

Visto en: smashingmagazine

EDITO: releyendo el post veo que no he puesto en ningún sitio que hay que cargar jQuery para hacerlo funcionar… Lo he dado por entendido al tratarse de un script en jQuery, pero por si alguien no se había dado cuenta, en el de la web donde vaya este código, hay que cargar jQuery. Yo lo suelo cargar del cdn de Google para evitar usar recursos de mi servidor, con esta línea:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
type="text/javascript" charset="utf-8"></script>

49 respuestas

    1. Hola Julio,

      Claro! si tienes la opción de editar el template, puedes ponerlo y debería funcionar. Es un script que no depende de la plataforma que uses, sea Blogger, WordPress o lo que sea.

      Saludos.

      1. Hay que tener un poco de cuidado con este código, si tienes conocimientos de javascript sabrás que que el “return false;” que devuelve al final del código parará todos los procesos ‘javascript’ que estén funcionando en ese momento, un ejemplo; un “Tab” que sería un botón en una página que te envía a otro contenido (‘div’) en la misma web y ocultando el contenido actual que estás visualizando sin recargar la página, con ese “return false;” perdería la interacción ya que los tabs que yo conozco están basados en javascript, también funcionan con anclajes a un ID (‘#’) y son una herramienta de ‘Bootstrap’ que normalmente se utiliza en los ‘gestores de contenido’ como por ejemplo WordPress.
        También es importante saber que en las versiones de jQuery migrate 1.3.0, jQuery 2.2.0 y jQuery 3.2.1 se han detectado errores por el selector ‘#’ devolviendo que no es valido, ya que es uno de los “caracteres especiales” no permitidos en las librerías jQuery con las versiones anteriormente mencionadas, necesita un comando de escape que quedaría así; ‘a[href*=\\#]’ y con el cual no te daría este error.
        Con el siguiente código no interfieres en ningún posible problema de los comentados y recomiendo tener siempre presente el código introducido en la Web para “posibles problemas” que pueda ocasionar, hay que mencionar que no me hago responsable de los posibles problemas que pueda ocasionar este código en tu Web y que siempre es mejor consultar a un experto en el campo que en este caso es Programador de Javascript.
        Un saludo y gracias por el contenido ya que me sirvió de ayuda :)

        Código actualizado sin errores:

        // Scroll animado

        $(function(){
        $(‘a[href*=\\#]’).click(function() {
        if (location.pathname.replace(/^\//,”) == this.pathname.replace(/^\//,”)
        && location.hostname == this.hostname) {
        var $target = $(this.hash);
        $target = $target.length && $target || $(‘[name=’ + this.hash.slice(1) +’]’);
        if ($target.length) {
        var targetOffset = $target.offset().top;
        $(‘html,body’).animate({scrollTop: targetOffset}, 1000);
        }
        }
        });
        });

          1. Yo puse el código en una web desarrollada por mí completamente, si estás utilizando un gestor de contenido tipo WordPress no puedo asegurarte que esto no produzca algún tipo de conflicto, te dejo mi código completo y si especificas el error podríamos ayudarte mejor, un saludo.
            https://codepen.io/anon/pen/LdGRqg?editors=1111

          2. ¡ Por nada ! ;-)
            Pero tener en cuenta que todo esto pasa por jQuery y puede ocasionar algún problema,
            yo para una web compleja optaría por centrarme en que los selectores del contenedor de los “anclajes” sean únicos y no engloben el ‘body’, también se podría buscar una librería especifica para esto que sería una buena opción aunque mucho más compleja o buscar en ‘codepen’ algún ejemplo más elaborado y que se adapte a tus necesidades.
            Ya tienes este código para salir del apuro y para la base de tu solución, en ningún caso intento desvalorar el gran trabajo de Verónica Milán, a mí personalmente me sacó de un apuro, actualmente estoy utilizando el código y es la base de mi solución, pero todo se puede mejorar, escalar y actualizar, sobretodo si son 10 líneas de código jejeje.

            Mi temor es que estamos englobando todo lo que contiene el body en la interacción y cualquier etiqueta ‘a’ con ‘href’ podrá darte un error inesperado, ejemplo;

            Supongamos que estás con un proyecto para un cliente y le dejas varios de los típicos enlaces de muestra con ‘href’ a ninguna parte (href=”#”) para que pueda clickear en ellos, pues con este código te dará un error y después de hacer algunas pruebas podrás ver que exactamente será este;

            /*! Versión: jQuery v3.2.1 */

            Uncaught Error: Syntax error, unrecognized expression: [name=]
            at Function.Sizzle.error (jquery.js:1580)
            at Sizzle.tokenize (jquery.js:2232)
            at Sizzle.select (jquery.js:2659)
            at Function.Sizzle [as find] (jquery.js:884)
            at jQuery.fn.init.find (jquery.js:2922)
            at new jQuery.fn.init (jquery.js:3032)
            at jQuery (jquery.js:98)
            ——> at HTMLAnchorElement. (utils.js:275) <———– línea donde empieza mi código

            at HTMLAnchorElement.dispatch (jquery.js:5206)
            at HTMLAnchorElement.elemData.handle (jquery.js:5014)

            Esto pasó al entrarle la cadena vacía y no haber definido nada para actuar en tal caso, por eso comento que se puede buscar algo más elaborado o escalar el código según tus necesidades, os ahorrará muchos dolores de cabeza jejeje, un saludo.
            Enmanuel.

  1. Hola! este código funciona a la perfección, pero en una web donde tengo una galería lightbox con jquery, al poner esta función a las anclas la galería deja de funcionar.
    ¿Alguna solución?
    Gracias

  2. Excelente muchas gracias por el aporte. Es posible q cuando se desplace a alguna seccion, el color de la seccion en el menu cambie? para indicar a traves del menú en que seccion se está?

  3. Eres lo mejor, te pasaste. Era justo lo que necesitaba, ahora solo quisiera entender bien el código para poder hacerle variaciones por si algún día lo necesito.

  4. Muy buen aporte… solo comentar para quienes tengan como yo la costubre de poner el código jquery al final de la página: No funciona al final, haa de ponerse al principio. Dado que si no funcionan normales los vinculos.

  5. Solo una duda, como puedo hacer el mismo efecto y accion, pero estando en una ventana, me redireccione a otra ventana y se deslice a una parte.?

  6. muy bien explicado espero sigas revisando, pero como lo hago funcionar el script en Joomla 3.X
    lo he intentado y no funciona

  7. hola,me parecio muy buen el script, te hago una sola consulta, para ayudar a facilitar la búsqueda aun mas, como se hace para que se salte el contenido del div una vez hecho el click de búsqueda?
    Saludos!

  8. Muy buen còdigo, soy novato y con este còdigo me funcioò a la perfecciòn, el tema es que ahora tengo otro problema, yo tenìa un còdigo de jquery en mi web para un enlace que tengo en el bottom de la pagina que dice: VOLVER ARRIBA , ahora este boton no funciona correctamente con el còdigo que nos brindaste, se podrà solucionar de alguna manera ?
    Mil gracias !

  9. Hola! He activado esta animación de jQuery en una web y funciona correctamente. Mi problema consiste en que cuando activo la animación deja de funcionar un evento de ratón que tengo aplicado en el mismo botón con JavaScript. Pienso que entran en conflicto las dos funciones y solo se aplica la animación. Me gustaría saber como puedo hacer que las dos funciones se activen al mismo tiempo.
    Muchas gracias y un saludo!

  10. Gracias!!
    Funciona a la perfeccion, solo añadir que para los usuarios de drupal es necesario cambiar el $ por jQuery

    Un abrazo

Deja una respuesta