jQuery / Methode / .scrollTop() - Vertikale Scrollposition lesen und setzen

jQuerys .scrollTop() liest die aktuelle vertikale Scrollposition des ersten Ziels; .scrollTop(120) setzt sie bei allen ausgewählten Zielen. Für die Seite wählen Sie $(window), für einen inneren Scrollcontainer das jeweilige Element. Das ist nicht dessen Dokumentposition.

Scrollziel und Position unterscheiden

Die .scrollTop()-API misst oben verborgenen Inhalt in CSS-Pixeln. Bei normalem Fluss von oben nach unten ist der Anfang null und der Wert steigt nach unten. Gemeint sind weder Bildschirmkoordinaten des Scrollgriffs noch CSS top.

Aufgabe Ziel und Aufruf Voraussetzung
Seitenposition lesen $(window).scrollTop() Dokument höher als Viewport
Box auf 120px setzen $("#box").scrollTop(120) Begrenzte Höhe und überlaufender Inhalt
Zum Anfang Ziel.scrollTop(0) Tatsächlich scrollendes Ziel

Native Werte liefern auch Element.scrollTop und window.scrollY. Hier behandelt jQuery beide mit derselben Methode. Lesen allein verschiebt nichts.

Vollständiger Vergleich von Seite und Box

Speichern Sie alles in UTF-8 als scroll-demo.html und öffnen Sie es im Browser. Die offizielle jQuery-Datei 4.0.0 vom Content Delivery Network (CDN) benötigt Internet, keine Installation. Positionen, übergroße Anforderungen, Reset und Konsolencode wurden mit 3.7.1 und 4.0.0 in Edge unter Windows ausgeführt.

Das Dokument ist mindestens 2000px hoch, die Box liegt bei Dokument-top 500px. Sechs 100px-Zeilen ergeben 600px Inhalt bei 160px sichtbarer Innenhöhe: maximal 600 - 160 = 440px. Rahmen liegen außerhalb der Innenhöhe. scroll-behavior:auto ermöglicht den direkten Vergleich.

<!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>

Die Anfangsausgabe gilt bei beiden Positionen null. Ist Ihr Viewport höher als 2000px und die Seite läuft nicht über, verkleinern Sie ihn für den Seitentest.

window=0
box=0
box max=440
at bottom=false
  1. Box to 120 setzt box=120, window bleibt null. Alpha verschwindet teilweise oben, weitere Zeilen erscheinen.
  2. Page to 300 ergibt window=300 und box=120. Die Box auf dem Bildschirm und ihr Inhalt bewegen sich unabhängig.
  3. Box to bottom fordert 1000000 an, wird bei dieser normalen Box aber auf 440 begrenzt. at bottom wird true.
  4. Direktes Scrollen oder Tastaturbedienung in der Box aktualisiert deren Bericht. Feste Bedienelemente halten beide Werte sichtbar.
  5. Reset both setzt Box und Fenster getrennt auf null. Wiederholungen ergeben die Anfangsausgabe.

Registrieren Sie scroll direkt am scrollenden Element. window scroll behandelt nicht automatisch die innere Box. report() liest beide Werte und berechnet das Maximum jedes Mal neu.

Maximum, Ende und mehrere Elemente

Für normale vertikale Container ist das Maximum Math.max(0, scrollHeight - clientHeight). scrollHeight beschreibt Inhaltshöhe, clientHeight den sichtbaren Innenraum. Das Beispiel verlangt ein positives Maximum und höchstens 1px Differenz zum Ende, statt genauer Gleichheit bei möglichen Nachkommastellen.

Ohne Überlauf kann die Position trotz Anforderung null bleiben. Hier gilt dann at bottom=false; ob kurze Boxen als bereits am Ende zählen, hängt von Ihrer Oberfläche ab. Bilder, Schriften oder Größenänderungen verändern möglicherweise Höhe und Maximum.

Führen Sie Folgendes in derselben Entwicklerkonsole aus. Temporäre Boxen erhalten unterschiedliche Positionen: Lesen der Menge liefert nur die erste, Setzen auf 80 verändert beide. Abschließend wird der temporäre Bereich entfernt.

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

Leere Getter liefern undefined. Die Zahl 0 ist eine gültige Position, kein fehlendes Ziel. Prüfen Sie bei erwartetem Ziel .length, das tatsächliche Scrollelement und die Bereitschaft des Document Object Model (DOM).

Keine Bewegung oder andere Werte untersuchen

overflow-y:auto allein genügt nicht, wenn die Box auf Inhaltshöhe wächst. Prüfen Sie Höhe beziehungsweise Maximalhöhe mit scrollHeight/clientHeight. Scrollt ein Vorfahr statt des ausgewählten Kindes, kann dessen Wert null bleiben.

Verwenden Sie window für die Seite, um Container zu unterscheiden. Der numerische Setter fordert selbst keine zeitgesteuerte jQuery-Animation an. Externes CSS für sanftes Scrollen oder Effektcode kann das Timing verändern; behandeln Sie Zwischenwerte nicht als Endergebnis.

Werte sind nicht überall ganzzahlig oder nichtnegativ. MDN beschreibt Nachkommastellen, negative Positionen bei column-reverse und Safaris Überscrollen. Der geprüfte Bereich 0–440 gilt für diese normale Box in Edge. Prüfen Sie bei anderen Layouts Richtung und Browserverhalten.