Scroll en jQuery

  • Por
Cuáles son las posibilidades de trabajo con funcionalidades relacionadas con el scroll en jQuery, ya sea en ventanas, elementos, animaciones con scroll, eventos de scroll, etc.

Una de las facetas típicas donde podemos sacar un buen partido de jQuery es trabajando con las propiedades de scroll de la ventana o los elementos. Para realización de interfaces de usuario y para la interacción con el cliente es interesante poder detectar el scroll actual, así como realizar eventos y animaciones con scroll.

Todo eso lo veremos en este taller de jQuery por medio de sencillos ejemplos que nos permitrán implementar comportamientos típicos. Yendo un poco más allá, estas técnicas que presentaremos son las mismas que utilizarías para un efecto de Paralax.

Detección del scroll actual

Lo primero que aprenderemos es a detectar la cantidad de scroll que se ha realizado sobre la página entera. En jQuery existe un método para obtener el valor del scroll actual en la vertical y otro para la horizontal: scrollTop() y scrollLeft(). No reciben ningún valor, simplemente devuelven la cantidad de píxels de desplazamiento.

Si quieres saber el desplazamiento de la página entera en un momento dado, invocas a estos métodos a partir del objeto document extendido con jQuery.

//scroll vertical
var sv = $(document).scrollTop();
//scroll horizontal
var sh = $(document).scrollLeft();

Estos dos métodos en jQuery sirven también para detectar el scroll actual en un elemento de la página sobre el que se pueda hacer desplazamiento.

Nota: Con CSS podemos crear elementos que tengan barras de desplazamiento gracias al atributo overflow. En general el elemento tendrá scroll cuando no quepan los elementos en las dimensiones asignadas. Por ejemplo en una caja de 200px de anchura colocamos una imagen de 300px de anchura. El scroll se puede configurar para que salga con overflow: auto (saldrá solo si no caben los elementos) o overflow: scroll (las barras para desplazar saldrán siempre).

var elemento = $(".elementoconscroll") //se supone que el elemento tendrá barras de deslazamiento
var sh = elemento.scrollLeft();

Animación con scroll

El segundo objetivo que podremos tener cuando trabajamos con desplazamientos sería el de realizar animaciones de scroll, ya sea desplazando toda la página o algo que hay en una caja en concreto. Como otras animaciones de jQuery usamos el método animate().

En caso que quieras realizar un desplazamiento de toda la página, el elemento que deberíamos animar sería BODY, pero para que funcione en todos los navegadores también tienes que producir esa animación sobre el elemento HTML.

La propiedad que debes animar es "scrollTop", asígnando un valor numérico que corresponde con el número de píxeles de la posición nueva a la que quieres desplazarte.

$("html, body").animate({
    scrollTop: 290
}, 2000);

Quizás te preguntes ¿Cómo hacer para que el scroll se sitúe en la posición de un elemento? pues se trata simplemente de buscar la posición de ese elemento en la página y una vez tienes ese valor, produces la animación.

$("#animarscroll").on("click", function(){
    var posicion = $("#hastaaqui").offset().top;
    $("html, body").animate({
        scrollTop: posicion
    }, 2000); 
});

Nota: La posición de un elemento con respecto al origen del documento la obtienes a través de offset(). Eso se explicó anteriormente en el artículo Posición y tamaño en jQuery. Además también tenemos un vídeo con un tutorial para ver las explicaciones de offset en ejemplos prácticos.

Por supuesto, de una manera similar a lo que viste en el punto anterior, puedes realizar animaciones con desplazamiento dentro de un elemento de la página, en vez de en la página completa. En ese caso simplemente ejecutas el método animate() sobre el elemento cuyo scroll quieres modificar.

Eventos con scroll

Ahora aprenderemos a crear eventos que se lanzan cuando el usuario está haciendo scroll en la página. Las posibilidades son amplias, desde el típico efecto de "Ajax infinity", hasta el botón de "ir hacia arriba" que aparece en muchas páginas cuando comienzas a hacer scroll para abajo, o animaciones Paralax que se ejecutan cuando lleguamos a un punto del documento, de modo que ocurran cosas como mostrar elementos, ocultarlos, moverlos, etc.

El evento que debemos usar es "scroll". Fácil de memorizar. Si queremos asociar eventos al movimiento de la página completa, lo asociamos al objeto window o document (una vez extendido con jQuery). Lógicamente, si lo que queremos es producir eventos cuando el scroll se realiza sobre un elemento, asociaremos el evento "scroll" sobre ese elemento.

En este ejemplo vamos a definir un evento scroll para que, cuando se desplace la página hacia abajo, aparezca una caja con un enlace que nos permita ir hacia arriba. La caja se supone que está ya en el DOM de la página, en un elemento con el id="irarriba".

$(document).on("scroll", function(){
    //sacamos el desplazamiento actual de la página
    var desplazamientoActual = $(document).scrollTop();
    //accedemos al control de "ir arriba"
    var controlArriba = $("#irarriba");
    //compruebo si debo mostrar el botón
    if(desplazamientoActual > 100 && controlArriba.css("display") == "none"){
        controlArriba.fadeIn(500);
    }
    //controlo si debo ocultar el botón
    if(desplazamientoActual < 100 && controlArriba.css("display") == "block"){
        controlArriba.fadeOut(500);
    }
});

Es muy sencillo y el código lo tienes comentado para entenderlo mejor. Ahora te preguntarás, cómo hacer para que el control #irarriba nos lleve verdaderamente hasta la parte de arriba de la página. Eso ya lo podrás imaginar, pues es una animación de desplazamiento, que hemos visto en el anterior punto.

$("#irarriba a").on("click", function(e){
    e.preventDefault();
    $("html, body").animate({
        scrollTop: 0
    }, 1000); 
});

Con esto hemos repasado más o menos todos los casos prácticos donde podemos necesitar controlar el scroll de la página o de los elementos. No deberías tener problemas para reproducir por ti mismo un ejemplo completo donde se realicen desplazamientos o eventos de desplazamiento.

De todos modos, te dejamos el código completo de un ejemplo para que lo pongas en marcha tú mismo.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Scroll</title>
    <style>
    #detectascroll{
        background-color: #cfc;
    }
    body{
        font-size: 1.2em;
    }
    p{
        max-width: 800px;
    }
    .mayor{
        width: 3500px;
        padding: 20px;
        background-color: #ccf;
    }
    .conscroll{
        height: 90px;
        width: 320px;
        padding: 15px;
        overflow: scroll;
        background-color: #cdd;
    }
    #animarscroll{
        background-color: #fcc;
    }
    #hastaaqui{
        background-color: #900;
        padding: 10px;
        color: white;
        font-size: 0.6em;
        width: 200px;
    }
    #irarriba{
        padding: 5px;
        position: fixed;
        bottom: 40px;
        right: 50px;
        background-color: #009;
        font-weight: bold;
        width: 50px;
        font-size: 0.8em;
        text-align: center;
        display: none;
    }
    #irarriba a{
        color: #fff;
    }
    </style>
</head>
<body>
   <div class="mayor">Este DIV se sale!!</div>
    <p>Lorem...</p>
    <p>Lorem...</p>
    <button id="detectascroll">Detecta el scroll <span></span></button> <button id="animarscroll">Animar hasta la caja roja</button>
    <p>Lorem...</p>
    <div class="conscroll">
        <p>Este párrafo y la siguiente lista están en una división que tiene scroll.</p>
        <button id="scrollelemento">Saber el scroll en el elemento <span></span></button>
        <ul>
            <li><a href="">enlace 1</a></li>
            <li><a href="">enlace 2</a></li>
            <li><a href="">enlace 3</a></li>
            <li><a href="">enlace 4</a></li>
            <li><a href="">enlace 5</a></li>
        </ul>
    </div>
    <p>Lorem...</p>
    <p>Lorem...</p>
    <p>Lorem...</p>
    <div id="hastaaqui">Animar scroll hasta aquí</div>
    <p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<p>Lorem...</p>
<div id="irarriba"><a href="#">Ir arriba</a></div>
    
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script>
    $(function(){
        $("#detectascroll").on("click", function () {
            //scroll vertical
            var sv = $(document).scrollTop();
            //scroll horizontal
            var sh = $(document).scrollLeft();
            console.log("El scroll es: Vertical->", sv, " Horizontal->" , sh);
            $(this).find("span").text("(" + sh + "," + sv+ ")");
        });
        $("#scrollelemento").on("click", function () {
            var boton = $(this);
            var elemento = boton.parent();
            //scroll vertical
            var sv = elemento.scrollTop();
            //scroll horizontal
            var sh = elemento.scrollLeft();
            console.log("El scroll del elemento es: Vertical->", sv, " Horizontal->" , sh);
            boton.find("span").text("(" + sh + "," + sv+ ")");
        });
        $("#animarscroll").on("click", function(){
            var posicion = $("#hastaaqui").offset().top;
            $("html, body").animate({
                scrollTop: posicion
            }, 2000); 
        });
        $(document).on("scroll", function(){
            var desplazamientoActual = $(document).scrollTop();
            var controlArriba = $("#irarriba");
            console.log("Estoy en " , desplazamientoActual); 
            if(desplazamientoActual > 100 && controlArriba.css("display") == "none"){
                controlArriba.fadeIn(500);
            }
            if(desplazamientoActual < 100 && controlArriba.css("display") == "block"){
                controlArriba.fadeOut(500);
            }
        });
        $("#irarriba a").on("click", function(e){
            e.preventDefault();
            $("html, body").animate({
                scrollTop: 0
            }, 1000); 
        });
    });
    </script>
</body>
</html>

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Karen

03/3/2015
Muy util!
Es justo lo que estaba buscando, ya he guardado el link para revisarlo mas adelante. Muchas gracias !

Sergio Barros

04/3/2015
Muy completo el artículo
Muy interesante, ahora nos quedamos con ganas de un ejemplo más complejo que usarías para un efecto parallax.

Karen

18/3/2015
Gracias
Me ha sido muy útil, gracias por compartir esta información.

Alex

06/6/2015
Ayuda!
Buenas,

De principio felicitaros por sus manuales son de gran ayuda.
Mi caso es el siguiente:
Tengo un contenedor (con proporciones fijas y estilo overflow:hidden) con texto dividido
en varias secciones y un menú lateral, quiero que al pulsar una sección del menú anime
el contenedor hasta llevarme a la sección seleccionada.
Lo he intentado de mil maneras y siempre me mueve el body (también tiene un overflow:hidden).

Un saludo!

Lucas

08/7/2015
contenedores
Hola Alex,
Así en crudo con lo que dices no sé que problema tendrás al hacer el scroll. Lo que te sugiero es que lances mensajes a la consola console.log() para ver los offset que tienen los elementos a los que quieres dirigir el scroll. El offset lo sacas con jquery con código que puedes ver en este mismo artículo.
Luego mirar los selectores q estás usando, que también te pueden dar problemas diversos y quizás no estás alcanzando los elementos que quieres.
El típico debug, vamos.

Julio

02/9/2015
Scroll Automatico
Un saludo, muy buen material gracias, me gustaría saber como hacer para que el scroll se mueva solo cada cierto tiempo sin que el usuario tenga que intervenir.

Ale

11/2/2016
Genial
Muchas gracias, super explicado!

Sergio Sanchez

01/11/2016
Duda sobre scroll
Gracias de antemano porel aporte. Lo que busco yo es hacer una navegacion de forma horizontal similar a la de apps como facebook o whatsaap que cuando quieres avanzar a otra seccion (ya sea la derecha o ala izquierda) al llegar a cierto punto del ancho del contenido actual, automáticamente el scroll se situa en la siguiente seccion y deja centrado el contenido. Ojala pudieran ayudarme sobre esto.

Muchas gracias.

jaime grijalbo

09/12/2016
Mantener la posición de DATATABLE, al actualzar.
Tengo una pagina HTML que se activa con JavaScript y se comunica con mysql mediante php... La tabla utiliza el plug DATATABLE y se pueden editar los campos de la tabla mediente el plug makeEditable.
Resulta que cuanto se actualiza algún campo de la tabla se me iba arriba a la izquierda y buscando encontré el script mostrado adelante que mantiene la posición vertical donde hice la actualización pero no la vertical, volviéndose arriba... Quisiera una ayuda para que mantenga tanto la posición vertical como horizontal al actualizar.
<script>
window.onload=function(){
var pos=window.name || 0;
window.scrollTo(0,pos);
}
window.onunload=function(){
window.name=self.pageYOffset || (document.documentElement.scrollTop+document.body.scrollTop);
}
</script>

abel

12/6/2017
edge animate
Hola amigo. Muchas gracias por el tuto. Mi pregunta es, cómo pueod usar ese codigo en edge animate, Gracias.

anita

19/7/2017
problema entre scroll de slide Y SCROLL DE LA PAGINA
ESTIMADO, TENGO UN PROBLEMA AL IMPLEMENTAR UN SLIDE, EL SCROLL DE LA PAGINA EN SI MISMA, CUANDO GIRO LA RUEDA SIN TOCARLO, NO ME FUNCIONA, TENES ALGUNA IDEA DE QUE CODIGO COLOCAR EN EL "BODY" COMO PARA ARREGLAR ESTE ERROR? GRACIAS!


ANA

Pablo

12/6/2018
MUY UTIL
Excelente Aporte.<br />
Me ha servido muchísimo la información brindada, mil gracias.

Emil

11/1/2019
Scroll Fijo - Ayuda
Hola, tengo días investigando esto:
Tengo una ventana de chat que se actualiza mediante AJAX es decir que carga los mensajes los actualiza pero tengo que ponerlos que los nuevos mensajes aparezcan arribas en el inicio del DIV, lo que quiero hacer es al revés que el SCROLL siempre aparezca abajo para yo poder que los mensajes recientes estén abajo.