Javascript: Wie erkennt man, ob das Browserfenster nach unten gescrollt ist?

185

Ich muss erkennen, ob ein Benutzer zum Ende einer Seite gescrollt ist. Wenn sie sich am Ende der Seite befinden und ich neuen Inhalt am unteren Rand hinzufüge, scrolle ich sie automatisch zum neuen unteren Rand. Wenn sie nicht unten sind, lesen sie den vorherigen Inhalt weiter oben auf der Seite, daher möchte ich sie nicht automatisch scrollen, da sie dort bleiben möchten, wo sie sind.

Wie kann ich feststellen, ob ein Benutzer zum Ende der Seite gescrollt ist oder ob er auf der Seite höher gescrollt hat?

Andrew
quelle
1
Dieser wird in Angular 6 -> stackoverflow.com/a/42547136/621951
Günay Gültekin

Antworten:

266
window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // you're at the bottom of the page
    }
};

Siehe Demo

mVChr
quelle
28
Funktioniert nicht, wenn HTML / Body-Elemente auf 100% eingestellt sind (so dass der Body die gesamte Höhe des Ansichtsfensters ausfüllt)
Grodriguez
5
Verwenden Sie document.documentElement.scrollTopanstelle window.scrollYfür IE. Nicht sicher, welche Versionen des IE gegebenenfalls unterstützt werden window.scrollY.
Batandwa
3
Funktioniert nicht in Chromium Version 47.0.2526.73. Entwickelt unter Ubuntu 14.04, läuft unter elementarem Betriebssystem 0.3.2 (64-Bit)
K - Die Toxizität in SO nimmt zu.
9
Ich habe document.body.scrollHeight anstelle von offsetHeight verwendet (in meinem Fall war offsetHeight immer kleiner als das window.innerHeight)
Oliver
1
@KarlMorrison können Sie die mit Kopfgeldern ausgezeichnete Antwort (von @Dekel) mit Ihrem Browser ausprobieren?
Basj
113

Aktualisierter Code für die Unterstützung aller gängigen Browser (einschließlich IE10 und IE11)

window.onscroll = function(ev) {
    if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Das Problem mit der aktuell akzeptierten Antwort ist das window.scrollY sie im IE nicht verfügbar ist.

Hier ist ein Zitat von mdn zu scrollY:

Verwenden Sie aus Gründen der browserübergreifenden Kompatibilität window.pageYOffset anstelle von window.scrollY.

Und ein funktionierender Ausschnitt:

Hinweis für Mac

Basierend auf dem Kommentar von @ Raphaël gab es ein Problem mit dem Mac aufgrund eines kleinen Versatzes.
Die folgende aktualisierte Bedingung funktioniert:

(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2

Ich hatte keine Gelegenheit, es weiter zu testen. Wenn jemand zu diesem speziellen Thema einen Kommentar abgeben kann, ist es großartig.

Dekel
quelle
Bestätigte Arbeit an FF, Chrome, IE10, Chrome für Android. Danke @Dekel!
Basj
2
So seltsam es auch klingen mag, nur in meinem Browser fehlt mir 1 Pixel, und daher wird der Zustand nicht ausgelöst. Ich bin mir nicht sicher warum, musste ein paar zusätzliche Pixel hinzufügen, damit es funktioniert.
Sharjeel Ahmed
3
Auf Mac-Computern ist die folgende Bedingung aufgrund eines kleinen Versatzes (~ 1 Pixel) nicht erfüllt. Wir haben die Bedingung wie folgt aktualisiert(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
Raphaël
4
Danke @Dekel! Tatsächlich finden wir heraus, dass window.pageYOffset ein Float auf dem Mac ist. Unsere endgültige Lösung ist (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
Raphaël
2
Funktioniert nicht in Fällen, in denen der Körper einen Stil hat, der die Höhe auf 100%
festlegt
56

Die akzeptierte Antwort hat bei mir nicht funktioniert. Dies tat:

window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
      // you're at the bottom of the page
      console.log("Bottom of page");
    }
};

Wenn Sie ältere Browser (IE9) unterstützen möchten, verwenden Sie den Alias, window.pageYOffsetder etwas besser unterstützt wird.

Ryan Knell
quelle
1
funktioniert nicht in IE10 / 11. Überprüfen Sie die Antwort von Dekel ( stackoverflow.com/questions/9439725/… ) auf IE-Unterstützung. Arbeitete für mich
Herr_Schwabullek
Die anderen Antworten lösten bei jedem Bildlauf die Datei console.log () aus, nicht nur, wenn ich mich am Ende der Seite befand. Diese Antwort hat bei Chrome funktioniert.
Defcronyke
Wenn Sie window.scrollY loswerden, was in dh oder edge nicht funktioniert, ist dies eine anständige Antwort. Ersetzen Sie durch: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
colemerrick
21

Ich habe nach einer Antwort gesucht, aber keine genaue gefunden. Hier ist eine reine Javascript-Lösung, die zum Zeitpunkt dieser Antwort mit den neuesten Versionen von Firefox, IE und Chrome funktioniert:

// document.body.scrollTop alone should do the job but that actually works only in case of Chrome.
// With IE and Firefox it also works sometimes (seemingly with very simple pages where you have
// only a <pre> or something like that) but I don't know when. This hack seems to work always.
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

// Grodriguez's fix for scrollHeight:
// accounting for cases where html/body are set to height:100%
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;

// >= is needed because if the horizontal scrollbar is visible then window.innerHeight includes
// it and in that case the left side of the equation is somewhat greater.
var scrolledToBottom = (scrollTop + window.innerHeight) >= scrollHeight;

// As a bonus: how to scroll to the bottom programmatically by keeping the horizontal scrollpos:
// Since window.innerHeight includes the height of the horizontal scrollbar when it is visible
// the correct vertical scrollTop would be
// scrollHeight-window.innerHeight+sizeof(horizontal_scrollbar)
// Since we don't know the visibility/size of the horizontal scrollbar
// we scroll to scrollHeight that exceeds the value of the
// desired scrollTop but it seems to scroll to the bottom with all browsers
// without problems even when the horizontal scrollbar is visible.
var scrollLeft = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft;
window.scrollTo(scrollLeft, scrollHeight);
pasztorpisti
quelle
4
Dies funktionierte fast für mich, aber ich musste verwenden, ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)anstatt nur document.body.scrollHeightFälle zu berücksichtigen, in denen HTML / Körper auf Höhe eingestellt sind: 100%
Grodriguez
1
@Grodriguez Danke für die Info! Es könnte für uns in Zukunft nützlich sein! :-)
Pasztorpisti
14

Das funktioniert

window.onscroll = function() {

    // @var int totalPageHeight
    var totalPageHeight = document.body.scrollHeight; 

    // @var int scrollPoint
    var scrollPoint = window.scrollY + window.innerHeight;

    // check if we hit the bottom of the page
    if(scrollPoint >= totalPageHeight)
    {
        console.log("at the bottom");
    }
}

Wenn Sie ältere Browser (IE9) unterstützen möchten, ersetzen Sie window.scrollY durch window.pageYOffset

Ifeanyi Amadi
quelle
1
Diese Arbeit mit reagieren im Jahr 2019. Arbeit mit Körper 100% Größe, Wert mit HTML 100% Größe. Arbeit mit Chrom, Safari, Firefox, Edge.
wütend Kiwi
Nur eine Anmerkung: Die Benennung sollte geändert werden - Variablen sollten gewechselt werden. Da scrollHeight die Gesamtseitenhöhe und totalHeight den aktuellen Bildlaufpunkt anzeigt, ist dies etwas verwirrend.
Vladimir Marton
4

Ich habe gerade angefangen, mir das anzuschauen, und die Antworten hier haben mir geholfen, also danke dafür. Ich habe ein wenig erweitert, damit der Code bis zum IE7 sicher ist:

Hoffe, das erweist sich für jemanden als nützlich.

Hier, hab eine Geige;)

    <!DOCTYPE html>
<html>
<head>
    <style>
        div {
            height: 100px;
            border-bottom: 1px solid #ddd;
        }

        div:nth-child(even) {
            background: #CCC
        }

        div:nth-child(odd) {
            background: #FFF
        }

    </style>
</head>

<body>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</body>

<script type="text/javascript">
console.log("Doc Height = " + document.body.offsetHeight);
console.log("win Height = " + document.documentElement.clientHeight);
window.onscroll = function (ev) {
    var docHeight = document.body.offsetHeight;
    docHeight = docHeight == undefined ? window.document.documentElement.scrollHeight : docHeight;

    var winheight = window.innerHeight;
    winheight = winheight == undefined ? document.documentElement.clientHeight : winheight;

    var scrollpoint = window.scrollY;
    scrollpoint = scrollpoint == undefined ? window.document.documentElement.scrollTop : scrollpoint;

    if ((scrollpoint + winheight) >= docHeight) {
        alert("you're at the bottom");
    }
};
</script>
</html>
Craig Poole
quelle
Art von Arbeiten. Aber es ist nicht sehr genau. Es wird davon ausgegangen, dass es nach unten gescrollt wird, solange Sie sich innerhalb von etwa 16 Pixel vom Boden befinden.
Peter Hall
4

Wenn Sie height: 100%einen Container <div id="wrapper">festlegen, funktioniert der folgende Code (in Chrome getestet):

var wrapper = document.getElementById('wrapper');

wrapper.onscroll = function (evt) {
  if (wrapper.scrollTop + window.innerHeight >= wrapper.scrollHeight) {
    console.log('reached bottom!');
  }
}
Jeremy Bernier
quelle
3
window.onscroll = function(ev) {
    if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Diese Antwort wird Rand Fällen beheben, ist dies , weil pageYOffsetist , doublewährend innerHeightund offsetHeightsind long, so dass , wenn der Browser Ihnen die Informationen gibt, können Sie ein Pixel kurz sein. Zum Beispiel: Am Ende der Seite haben wir

wahr window.innerHeight = 10.2

wahr window.pageYOffset = 5.4

wahr document.body.offsetHeight = 15.6

Unsere Berechnung lautet dann: 10 + 5,4> = 16, was falsch ist

Um dies zu beheben, können wir Math.ceilden pageYOffsetWert ändern.

Hoffentlich hilft das.

itay yahalom
quelle
3

wenn du jquery liebst

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()) {
    // doSomethingHere();
  }
});
Eka Putra
quelle
Und wer liebt jQuery nicht ...
Josh Habdas
2
@ JoshHabdas Browser
Toni Michel Caubet
2

Sie können in die unendliche Schriftrolle von jquery schauen:

http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/

Das klingt so, als würde es das tun, wonach Sie fragen, vorausgesetzt, Sie sind bereit, die jquery-Bibliothek zu verwenden, und hoffen nicht auf eine strikte reine JS-Methode.

Kai Qing
quelle
2
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Bobthedeveloper
@ Hatjoem Er verlinkt auf ein Plugin. Was genau sind die "wesentlichen Teile", die kopiert werden sollten? Wen interessiert es, wenn die Antwort "ungültig wird, wenn sich die verlinkte Seite ändert"? Wenn der Link unterbrochen wird, bedeutet dies, dass das Plugin eingestellt wurde und nicht mehr existiert - selbst wenn Sie der Antwort weitere Informationen hinzufügen, ist es immer noch ungültig. Meine Güte, Nur-Link-Antworten sind nicht unbedingt schlecht.
Dcastro
@Hatsjoem Auch aus dem Meta : "Wenn sich die referenzierte Bibliothek an einem bekannten, stabilen Ort befindet, ist diese Art der Antwort eine allgemein schlechte Antwort, aber dennoch eine Antwort : Es heißt" benutze dies "."
Dcastro
Außerdem wird Google wahrscheinlich noch existieren, wenn diese URL durch unendlichen Bildlauf geändert wird. Der Punkt ist, dieses Plugin zu verwenden. Wenn der Link stirbt, einfach Google Search jquery infinite scroll. Sie werden wahrscheinlich finden, was Sie brauchen.
Kai Qing
2

Überraschenderweise hat keine der Lösungen für mich funktioniert. Ich denke, das liegt daran, dass ich cssdurcheinander war und bodybei der Verwendung nicht den gesamten Inhalt umhüllte height: 100%(ich weiß noch nicht warum). Auf der Suche nach einer Lösung habe ich mir jedoch etwas Gutes ausgedacht ... im Grunde das Gleiche, aber vielleicht lohnt es sich, es sich anzusehen - ich bin neu in der Programmierung. Es tut mir leid, wenn es das Gleiche langsamer macht, weniger unterstützt wird oder so Das...

window.onscroll = function(evt) {
  var check = (Element.getBoundingClientRect().bottom - window.innerHeight <= 0) ? true : false;
  if (check) { console.log("You're at the bottom!"); }
};
Coldark
quelle
2
$(document).ready(function(){
    $('.NameOfYourDiv').on('scroll',chk_scroll);
});

function chk_scroll(e)
{
    var elem = $(e.currentTarget);
    if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) 
    {
        alert("scrolled to the bottom");
    }

}
Zihan Zhang
quelle
idk eine andere Perspektive. Aber die akzeptierte Antwort ist sicher besser
Zihan Zhang
2
const handleScroll = () => {
    if (Math.round(window.scrollY + window.innerHeight) >= Math.round(document.body.scrollHeight)) {
        onScroll();
    }
};

Dieser Code funktionierte auch in Firefox und IE.

Arokia Prabha
quelle
1

Verwenden defaultViewund documentElementmit eingebettetem Funktionscode-Snippet:

const { defaultView } = document;
const { documentElement } = document;
const handler = evt => requestAnimationFrame(() => {
  const hitBottom = (() => (defaultView.innerHeight + defaultView.pageYOffset) >= documentElement.offsetHeight)();
  hitBottom
    ? console.log('yep')
    : console.log('nope')
});
document.addEventListener('scroll', handler);
<pre style="height:110vh;background-color:fuchsia">scroll down</pre>

Josh Habdas
quelle
1

Sie können überprüfen, ob das kombinierte Ergebnis aus Fensterhöhe und Bildlauf oben größer als das des Körpers ist

if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {}

Oussama Essamadi
quelle
0

Ich musste einen Weg finden (in Java), um systematisch nach unten zu scrollen und nach einer Komponente zu suchen, für die ich den richtigen XPath nicht kannte (lange Geschichte, also einfach mitspielen). Wie ich gerade sagte, musste ich bei der Suche nach einer Komponente nach unten scrollen und entweder anhalten, wenn die Komponente gefunden wurde oder der untere Rand der Seite erreicht war.

Das folgende Codefragment steuert das Scrollen nach unten zum Ende der Seite:

JavascriptExecutor js = (JavascriptExecutor) driver;
boolean found = false;
long currOffset = 0;
long oldOffset = 0;
do
{
    oldOffset = currOffset;
    // LOOP to seek the component using several xpath regexes removed
    js.executeScript("window.scrollBy(0, 100)");
    currOffset = (Long)js.executeScript("var offset = window.window.pageYOffset; return offset;");
} while (!found && (currOffset != oldOffset));

Das Fenster wird übrigens maximiert, bevor dieses Code-Snippet ausgeführt wird.

hfontanez
quelle
0

Die akzeptierte Antwort hat bei mir nicht funktioniert. Dies tat:

const element = document.createElement('div');
document.body.appendChild(element);
document.addEventListener('scroll', () => {
    const viewportHeight = window.innerHeight;
    const distance = element.getBoundingClientRect().top;
    if (Math.floor(distance) <= viewportHeight) {
        console.log('yep')
    } else {
        console.log('nope')
    }
})
mqliutie
quelle