jQuery / Método / .scrollTop() - Leer o establecer la posición vertical

En jQuery, .scrollTop() lee la posición vertical actual del primer destino y .scrollTop(120) la establece en todos. Seleccione $(window) para la página o el elemento para un contenedor interno. No es la posición del elemento en el documento.

Elegir el destino que se desplaza

La API de .scrollTop() mide en píxeles CSS contenido oculto por arriba. En flujo normal de arriba abajo, cero es el inicio y la cifra aumenta hacia abajo. No es la coordenada del control de la barra ni CSS top.

Tarea Destino y llamada Condición
Leer página $(window).scrollTop() Documento más alto que el área visible
Mover caja a 120px $("#box").scrollTop(120) Altura limitada y contenido desbordado
Volver arriba destino.scrollTop(0) Destino que realmente se desplaza

Las lecturas nativas son Element.scrollTop y window.scrollY. Aquí jQuery utiliza un método para ambos. Leer no mueve la vista.

Ejemplo completo de página y caja

Guarde todo el código en UTF-8 como scroll-demo.html y ábralo en el navegador. Se necesita Internet para el archivo oficial de jQuery 4.0.0 de la red de distribución de contenido (CDN), sin instalación. Posiciones, solicitudes excesivas, reinicio y consola se ejecutaron con 3.7.1 y 4.0.0 en Edge para Windows.

El documento mide al menos 2000px y la caja está en top 500px. Seis filas de 100px dan 600px de contenido con 160px interiores visibles: máximo 600 - 160 = 440px. Los bordes quedan fuera de esa altura. scroll-behavior:auto permite comparar directamente.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Separate page and element scroll positions</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    html { scroll-behavior: auto; }
    body { margin: 0; min-height: 2000px; font: 16px/1.6 sans-serif; }
    #controls { position: fixed; top: 0; left: 0; right: 0; z-index: 2; background: #fff; padding: 12px; max-height: 42vh; overflow: auto; }
    button { font: inherit; margin: 3px; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
    #box { position: absolute; top: 500px; left: 20px; right: 20px; max-width: 600px; height: 160px; overflow-y: auto; border: 2px solid teal; scroll-behavior: auto; }
    .row { height: 100px; box-sizing: border-box; padding: 12px; border-bottom: 1px solid #abc; background: #edf9f6; }
  </style>
</head>
<body>
  <div id="controls">
    <strong>Page and box scrolling</strong>
    <button type="button" id="box120">Box to 120</button>
    <button type="button" id="bottom">Box to bottom</button>
    <button type="button" id="page300">Page to 300</button>
    <button type="button" id="reset">Reset both</button>
    <pre id="result" aria-live="polite"></pre>
  </div>
  <div id="box" tabindex="0" aria-label="Scrollable example rows">
    <div class="row">Alpha</div><div class="row">Beta</div><div class="row">Gamma</div><div class="row">Delta</div><div class="row">Epsilon</div><div class="row">Zeta</div>
  </div>
  <script>
    $(function () {
      const $box = $("#box");
      function report() {
        const node = $box.get(0);
        const top = $box.scrollTop();
        const max = Math.max(0, node.scrollHeight - node.clientHeight);
        const bottom = max > 0 && Math.abs(max - top) <= 1;
        $("#result").text(`window=${$(window).scrollTop()}\nbox=${top}\nbox max=${max}\nat bottom=${bottom}`);
      }
      $("#box120").on("click", function () { $box.scrollTop(120); report(); });
      $("#bottom").on("click", function () { $box.scrollTop(1000000); report(); });
      $("#page300").on("click", function () { $(window).scrollTop(300); report(); });
      $("#reset").on("click", function () { $box.scrollTop(0); $(window).scrollTop(0); report(); });
      $box.on("scroll.scrollLesson", report);
      $(window).on("scroll.scrollLesson resize.scrollLesson", report);
      report();
    });
  </script>
</body>
</html>

La salida supone ambos destinos arriba. Si el área visible supera 2000px y la página no desborda, reduzca su altura para probar.

window=0
box=0
box max=440
at bottom=false
  1. Box to 120 da box=120 y mantiene window=0. Parte de Alpha queda oculta por arriba.
  2. Page to 300 da window=300, box=120. Mover la caja en pantalla es distinto de mover su contenido.
  3. Box to bottom solicita 1000000, pero esta caja normal limita a 440. at bottom pasa a true.
  4. Desplace directamente o use el teclado dentro de la caja para actualizar su evento scroll. Los controles fijos mantienen las lecturas accesibles.
  5. Reset both devuelve caja y ventana por separado a cero, incluso al repetir.

Registre scroll directamente en el elemento que se desplaza. window scroll no controla automáticamente la caja interna. report() lee ambas posiciones y recalcula el máximo.

Máximo, final y varios elementos

En una caja vertical normal, el máximo es Math.max(0, scrollHeight - clientHeight). scrollHeight mide contenido y clientHeight el interior visible. El ejemplo exige máximo positivo y diferencia de hasta 1px para detectar el final, sin igualdad estricta ante posibles fracciones.

Sin desbordamiento, una petición puede dejar cero. Aquí at bottom es false; considerar una caja corta ya al final depende de la interfaz. Imágenes, fuentes y dimensiones pueden cambiar altura y máximo.

Ejecute esto en la consola de la misma página. Dos cajas temporales reciben posiciones distintas. Consultar la colección da solo la primera; establecer 80 modifica ambas. Después se elimina el área temporal.

const $holder = $("<div>").appendTo("body");
const $boxes = $("<div></div><div></div>").css({ height: 40, overflowY: "auto" }).appendTo($holder);
$boxes.each(function () { $(this).append($("<div>").css("height", 200)); });
$boxes.eq(0).scrollTop(40);
$boxes.eq(1).scrollTop(100);
console.log(`first getter=${$boxes.scrollTop()}`);
$boxes.scrollTop(80);
console.log(`all=${$boxes.map(function () { return $(this).scrollTop(); }).get().join(",")}`);
console.log(`empty getter=${typeof $().scrollTop()}`);
$holder.remove();
first getter=40
all=80,80
empty getter=undefined

Una selección vacía devuelve undefined. Cero es una posición válida, no ausencia de destino. Compruebe .length, el elemento que se desplaza y la preparación del modelo de objetos del documento (DOM).

Investigar falta de movimiento o valores distintos

overflow-y:auto no basta si la caja crece con el contenido. Revise altura o altura máxima y scrollHeight/clientHeight. Si se desplaza un antecesor pero selecciona el hijo, este puede seguir en cero.

Use window para separar página y contenedores. Asignar un número no pide por sí solo una animación jQuery temporizada. CSS de desplazamiento suave u otros efectos pueden cambiar el momento: no confunda una lectura intermedia con el resultado final.

No todos los valores son enteros o no negativos. MDN describe fracciones, valores negativos con column-reverse y desplazamiento fuera de límites en Safari. El intervalo verificado 0–440 corresponde a esta caja normal en Edge. Para otros diseños, revise dirección y comportamiento del navegador.