Javascript: come rilevare se la finestra del browser è stata spostata verso il basso?


187

Devo rilevare se un utente scorre fino alla fine di una pagina. Se sono in fondo alla pagina, quando aggiungo nuovi contenuti in fondo, li farò scorrere automaticamente fino al nuovo fondo. Se non sono in fondo, stanno leggendo i contenuti precedenti più in alto nella pagina, quindi non voglio scorrere automaticamente perché vogliono rimanere dove sono.

Come posso rilevare se un utente è passato in fondo alla pagina o se ha fatto scorrere più in alto sulla pagina?


1
Questo è lavorato in Angular 6 ->
stackoverflow.com/a/42547136/621951

Risposte:


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

Vedi la demo


29
Non funziona quando gli elementi html / body sono impostati al 100% (in modo che il corpo riempia l'intera altezza della finestra)
Grodriguez,

5
Utilizzare document.documentElement.scrollTopinvece di window.scrollYIE. Non sono sicuro di quali versioni di IE siano supportate window.scrollY.
Batandwa,

3
Non funziona in Chromium Versione 47.0.2526.73 Costruito su Ubuntu 14.04, in esecuzione su SO elementare 0.3.2 (64-bit)
K - La tossicità in SO sta crescendo.

9
Ho usato document.body.scrollHeight invece di offsetHeight (nel mio caso, offsetHeight era sempre più piccolo di window.innerHeight)
Oliver

1
@KarlMorrison puoi provare la risposta premiata (da @Dekel) con il tuo browser?
Basj,

115

Codice aggiornato per tutti i principali browser supportati (include IE10 e IE11)

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

Il problema con l'attuale risposta accettata è quello window.scrollY non è disponibile in IE.

Ecco una citazione da mdn riguardante scrollY:

Per la compatibilità tra browser, utilizzare window.pageYOffset anziché window.scrollY.

E uno snippet funzionante:

Nota per mac

Sulla base del commento di @ Raphaël, c'era un problema nel mac a causa di un piccolo offset.
La seguente condizione aggiornata funziona:

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

Non ho avuto la possibilità di testarlo ulteriormente, se qualcuno può commentare questo specifico problema, sarà fantastico.


Confermato lavorando su FF, Chrome, IE10, Chrome per Android. Grazie @Dekel!
Basj,

2
Per quanto strano possa sembrare, solo nel mio browser sono a corto di 1 px, e quindi la condizione non viene attivata. Non so perché, ho dovuto aggiungere qualche px in più per farlo funzionare.
Sharjeel Ahmed,

3
sui computer Mac, la condizione di seguito non è soddisfatta a causa di un piccolo offset (~ 1px), abbiamo aggiornato la condizione in questo modo(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
Raphaël

4
grazie @Dekel! in realtà, scopriamo che window.pageYOffset è un float su Mac. La nostra soluzione finale è (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
Raphaël,

2
Non funziona nei casi in cui il corpo ha uno stile che imposta l'altezza al 100%
raRaRa

56

La risposta accettata non ha funzionato per me. Questo ha fatto:

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");
    }
};

Se stai cercando di supportare i browser più vecchi (IE9) usa l'alias window.pageYOffsetche ha un supporto leggermente migliore.


1
non funziona in IE10 / 11. Controlla la risposta di Dekel ( stackoverflow.com/questions/9439725/… ) per il supporto IE. Ha funzionato per me
Herr_Schwabullek il

Le altre risposte hanno attivato console.log () ogni volta che scorrevo, non solo quando ero in fondo alla pagina. Questa risposta ha funzionato per me su Chrome.
Defcronyke,

Se ti sbarazzi di window.scrollY, che non funziona in ie o edge, questa è una risposta decente. Sostituisci con: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
colemerrick

21

Stavo cercando una risposta ma non ne ho trovata una esatta. Ecco una soluzione javascript pura che funziona con gli ultimi Firefox, IE e Chrome al momento di questa risposta:

// 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);

4
Questo ha funzionato quasi per me, ma ho dovuto utilizzare ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)invece solo document.body.scrollHeightper tenere conto dei casi in cui html / body sono impostati su altezza: 100%
Grodriguez,

1
@Grodriguez Grazie per le informazioni! Potrebbe esserci utile in futuro! :-)
pasztorpisti,

15

Questo funziona

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");
    }
}

Se stai cercando di supportare i browser più vecchi (IE9) sostituisci window.scrollY con window.pageYOffset


1
questo lavoro con reagisce nel 2019. lavora con altezza del corpo del 100%, valore con altezza html del 100%. funziona con Chrome, Safari, Firefox, Edge.
kiwi arrabbiato,

Solo una nota: la denominazione dovrebbe essere cambiata, le variabili dovrebbero essere cambiate. Perché scrollHeight mostra l'altezza totale della pagina e totalHeight mostra il punto di scorrimento corrente, quindi è un po 'confuso.
Vladimir Marton,

4

Ho appena iniziato a guardare questo e le risposte qui mi hanno aiutato, quindi grazie per quello. Ho ampliato un po 'in modo che il codice sia al sicuro su IE7:

Spero che questo si riveli utile per qualcuno.

Ecco, prendi un violino;)

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

Sorta di opere. Ma non è molto preciso. Considera che è fatto scorrere verso il basso fintanto che sei all'interno di circa 16px dal fondo.
Peter Hall,

4

Se stai impostando height: 100%su un contenitore <div id="wrapper">, funziona il seguente codice (testato in Chrome):

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

wrapper.onscroll = function (evt) {
  if (wrapper.scrollTop + window.innerHeight >= wrapper.scrollHeight) {
    console.log('reached bottom!');
  }
}

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

Questa risposta risolverà casi limite, questo perché pageYOffsetè doublewhile innerHeighte offsetHeightarelong , in modo che quando il browser ti dà le informazioni, si può essere un breve pixel. Ad esempio: in fondo alla pagina abbiamo

vero window.innerHeight = 10.2

vero window.pageYOffset = 5.4

vero document.body.offsetHeight = 15.6

Il nostro calcolo diventa quindi: 10 + 5.4> = 16 che è falso

Per risolvere questo possiamo fare Math.ceilsulpageYOffset valore.

Spero che aiuti.


3

se ami jquery

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()) {
    // doSomethingHere();
  }
});

E chi non ama jQuery ...
Josh Habdas,

2
Browser @JoshHabdas
Toni Michel Caubet,

2

Puoi dare un'occhiata allo scroll infinito di jquery:

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

Il che suona come quello che fa per quello che stai chiedendo, supponendo che tu sia disposto a usare la libreria jquery e non sperare in un rigoroso metodo JS puro.


2
Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
bobthedeveloper

@Hatsjoem Sta collegando a un plugin. Quali sono esattamente le "parti essenziali" che dovrebbero essere copiate? A chi importa se la risposta "diventa non valida se la pagina collegata cambia"? Se il collegamento si interrompe, significa che il plug-in è stato sospeso e non esiste più - anche se aggiungi più informazioni alla risposta, rimarrebbe comunque non valido. Accidenti, le risposte solo link non sono necessariamente cattive.
dcastro,

@Hatsjoem Inoltre, da meta : "Quando la libreria a cui si fa riferimento si trova in una posizione ben nota e stabile, questo tipo di risposta è generalmente una risposta scarsa ma una risposta : dice" usa questo "."
dcastro,

Inoltre, probabilmente Google continuerà a esistere se lo scroll infinito modifica questo URL. Il punto è usare quel plug-in, quindi se il collegamento si interrompe, basta cercare google infinito scorrimento. Probabilmente troverai quello che ti serve.
Kai Qing,

2

Sorprendentemente nessuna delle soluzioni ha funzionato per me. Penso che sia perché il mio è cssstato incasinato e bodynon ha avvolto tutto il contenuto durante l'utilizzo height: 100%(non so ancora perché). Tuttavia, mentre cercavo una soluzione, ho escogitato qualcosa di buono ... praticamente lo stesso, ma forse vale la pena guardarlo: sono nuovo nella programmazione, quindi mi dispiace se sta facendo lo stesso più lentamente, è meno supportato o qualcosa del genere quello...

window.onscroll = function(evt) {
  var check = (Element.getBoundingClientRect().bottom - window.innerHeight <= 0) ? true : false;
  if (check) { console.log("You're at the bottom!"); }
};

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");
    }

}

idk una prospettiva diversa. Ma la risposta accettata è sicuramente migliore
Zihan Zhang,

2
const handleScroll = () => {
    if (Math.round(window.scrollY + window.innerHeight) >= Math.round(document.body.scrollHeight)) {
        onScroll();
    }
};

Questo codice ha funzionato anche per me in Firefox e IE.


1

Utilizzo defaultViewe documentElementcon lo snippet di codice funzionale incorporato:

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>


1

È possibile verificare se il risultato combinato dell'altezza della finestra e della parte superiore dello scorrimento è maggiore di quello del corpo

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


0

Ho dovuto trovare un modo (in Java) per scorrere sistematicamente verso il basso alla ricerca di un componente per il quale non conoscevo l'XPath corretto (lunga storia, quindi basta giocare). Come ho appena detto, ho dovuto scorrere verso il basso mentre cercavo un componente e fermarmi quando il componente è stato trovato o è stata raggiunta la parte inferiore della pagina.

Il frammento di codice seguente controlla lo scorrimento verso il basso nella parte inferiore della pagina:

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));

A proposito, la finestra viene ingrandita prima dell'esecuzione di questo frammento di codice.


0

La risposta accettata non ha funzionato per me. Questo ha fatto:

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')
    }
})

0

Due soluzioni che ho trovato che hanno funzionato per me:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })

E l'altro:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + window.pageYOffset ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.