Javascript: Comment détecter si la fenêtre du navigateur défile vers le bas?

193

J'ai besoin de détecter si un utilisateur fait défiler vers le bas d'une page. S'ils sont en bas de la page, lorsque j'ajoute du nouveau contenu en bas, je les ferai automatiquement défiler vers le nouveau bas. S'ils ne sont pas en bas, ils lisent le contenu précédent plus haut sur la page, donc je ne veux pas les faire défiler automatiquement car ils veulent rester là où ils sont.

Comment puis-je détecter si un utilisateur fait défiler vers le bas de la page ou s'il a défilé plus haut sur la page?

Andrew
la source
1
Celui-ci est travaillé dans Angular 6 -> stackoverflow.com/a/42547136/621951
Günay Gültekin

Réponses:

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

Voir la démo

mVChr
la source
30
Ne fonctionne pas lorsque les éléments html / body sont définis à 100% (de sorte que le corps remplisse toute la hauteur de la fenêtre)
Grodriguez
5
Utilisez document.documentElement.scrollTopau lieu de window.scrollYpour IE. Je ne sais pas, le cas échéant, les versions de support IE window.scrollY.
Batandwa
3
Ne fonctionne pas dans Chromium Version 47.0.2526.73 Construit sur Ubuntu 14.04, fonctionnant sous OS élémentaire 0.3.2 (64 bits)
basickarl
9
J'ai utilisé document.body.scrollHeight au lieu de offsetHeight (dans mon cas, offsetHeight était toujours plus petit que window.innerHeight)
Oliver
1
@KarlMorrison pouvez-vous essayer la réponse à la prime (par @Dekel) avec votre navigateur?
Basj
123

Code mis à jour pour tous les principaux navigateurs pris en charge (y compris IE10 et IE11)

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

Le problème avec la réponse actuellement acceptée est qu'elle window.scrollYn'est pas disponible dans IE.

Voici une citation de mdn concernant scrollY:

Pour une compatibilité entre navigateurs, utilisez window.pageYOffset au lieu de window.scrollY.

Et un extrait de code fonctionnel:

Remarque pour Mac

D'après le commentaire de @ Raphaël, il y a eu un problème sous mac à cause d'un petit décalage.
La condition mise à jour suivante fonctionne:

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

Je n'ai pas eu la chance de le tester davantage, si quelqu'un peut commenter ce problème spécifique, ce sera formidable.

Dekel
la source
Confirmation de travail sur FF, Chrome, IE10, Chrome pour Android. Merci @Dekel!
Basj
2
Aussi étrange que cela puisse paraître, il ne me manque que dans mon navigateur 1 px et la condition ne se déclenche donc pas. Je ne sais pas pourquoi, a dû ajouter quelques pixels supplémentaires pour que cela fonctionne.
Sharjeel Ahmed
3
sur les ordinateurs mac, la condition ci-dessous n'est pas remplie en raison d'un petit décalage (~ 1px) nous avons mis à jour la condition comme ceci(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
Raphaël
4
merci @Dekel! en fait, nous découvrons que window.pageYOffset est un float sur mac. Notre solution finale est (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
Raphaël
2
Ne fonctionne pas pour les cas où le corps a un style qui règle la hauteur à 100%
Jón Trausti Arason
58

La réponse acceptée n'a pas fonctionné pour moi. Cela a fait:

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

Si vous cherchez à prendre en charge des navigateurs plus anciens (IE9), utilisez l'alias window.pageYOffsetqui a un support légèrement meilleur.

Ryan Knell
la source
1
ne fonctionne pas dans IE10 / 11. Vérifiez la réponse de Dekel ( stackoverflow.com/questions/9439725/… ) pour la prise en charge d'IE. A travaillé pour moi
Herr_Schwabullek
Les autres réponses ont déclenché le console.log () à chaque fois que je faisais défiler, pas seulement lorsque j'étais en bas de page. Cette réponse a fonctionné pour moi sur Chrome.
Defcronyke
Si vous vous débarrassez de window.scrollY, qui ne fonctionne pas dans ie ou edge, c'est une réponse décente. Remplacer par: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
colemerrick
21

Je cherchais une réponse mais je n'ai pas trouvé de réponse exacte. Voici une solution javascript pure qui fonctionne avec les derniers Firefox, IE et Chrome au moment de cette réponse:

// 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
la source
4
Cela a presque fonctionné pour moi, mais j'ai dû utiliser ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)au lieu de juste document.body.scrollHeightpour tenir compte des cas où html / body sont réglés à la hauteur: 100%
Grodriguez
1
@Grodriguez Merci pour l'info! Cela peut nous être utile à l'avenir! :-)
pasztorpisti
18

Cela marche

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

Si vous souhaitez prendre en charge d'anciens navigateurs (IE9), remplacez window.scrollY par window.pageYOffset

Ifeanyi Amadi
la source
1
ce travail avec réagit en 2019. travail avec le corps 100% hauteur, vaut avec html 100% hauteur. fonctionne avec chrome, safari, firefox, edge.
angry kiwi
Juste une note: le nom doit être changé - les variables doivent être changées. Parce que scrollHeight montre la hauteur totale de la page, et totalHeight montre le point de défilement actuel, donc c'est un peu déroutant.
Vladimir Marton
1
C'était le seul qui a fonctionné pour moi, merci!
Dal
4

Je viens de commencer à regarder cela et les réponses ici m'ont aidé, alors merci pour cela. J'ai un peu développé pour que le code soit sûr jusqu'à IE7:

J'espère que cela sera utile pour quelqu'un.

Tiens, prends un violon;)

    <!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
la source
Sorte d'œuvres. Mais ce n'est pas très précis. Il considère qu'il défile vers le bas tant que vous êtes à environ 16 pixels du bas.
Peter Hall
4

Si vous configurez height: 100%sur un conteneur <div id="wrapper">, le code suivant fonctionne (testé dans Chrome):

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

wrapper.onscroll = function (evt) {
  if (wrapper.scrollTop + window.innerHeight >= wrapper.scrollHeight) {
    console.log('reached bottom!');
  }
}
Jérémy Bernier
la source
3
$(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
la source
idk une perspective différente. Mais la réponse acceptée est meilleure à coup sûr
Zihan Zhang
3
window.onscroll = function(ev) {
    if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Cette réponse corrigera les cas de bord, c'est parce que pageYOffsetc'est doublependant innerHeightet offsetHeightsont long, donc lorsque le navigateur vous donne les informations, vous pouvez être un pixel court. Par exemple: en bas de page, nous avons

vrai window.innerHeight = 10.2

vrai window.pageYOffset = 5.4

vrai document.body.offsetHeight = 15.6

Notre calcul devient alors: 10 + 5,4> = 16 ce qui est faux

Pour résoudre ce problème, nous pouvons faire Math.ceilsur la pageYOffsetvaleur.

J'espère que ça t'as aidé.

itay yahalom
la source
3

si vous aimez jquery

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()) {
    // doSomethingHere();
  }
});
Eka putra
la source
Et qui n'aime pas jQuery…
Josh Habdas
2
@JoshHabdas navigateurs
Toni Michel Caubet
2

Vous pouvez regarder dans le défilement infini de jquery:

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

Ce qui semble faire ce que vous demandez, en supposant que vous êtes prêt à utiliser la bibliothèque jquery et que vous n'espérez pas une méthode JS pure et stricte.

Kai Qing
la source
2
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change.
bobthedeveloper
@Hatsjoem Il crée un lien vers un plugin. Quelles sont exactement les «parties essentielles» à recopier? Qui se soucie si la réponse "devient invalide si la page liée change"? Si le lien est rompu, cela signifie que le plugin a été interrompu et n'existe plus - même si vous ajoutez plus d'informations à la réponse, il serait toujours invalide. Bon sang, les réponses aux liens uniquement ne sont pas nécessairement mauvaises.
dcastro
@Hatsjoem Aussi, à partir de meta : "Lorsque la bibliothèque référencée se trouve dans un emplacement stable et bien connu, ce genre de réponse est une réponse généralement médiocre mais néanmoins une réponse : il dit" utilisez ceci "."
dcastro
De plus, Google existera probablement toujours si le défilement infini modifie cette URL. Le but est d'utiliser ce plugin donc si le lien meurt, il suffit de rechercher Google jquery infinite scroll. Vous trouverez probablement ce dont vous avez besoin.
Kai Qing
2

Étonnamment, aucune des solutions n'a fonctionné pour moi. Je pense que c'est parce que mon a cssété foiré et bodyn'a pas enveloppé tout le contenu lors de l'utilisation height: 100%(je ne sais pas encore pourquoi). Cependant, en cherchant une solution, j'ai trouvé quelque chose de bien ... fondamentalement la même chose, mais peut-être que cela vaut la peine de regarder - je suis nouveau dans la programmation, désolé si cela fait la même chose plus lentement, est moins pris en charge ou quelque chose comme cette...

window.onscroll = function(evt) {
  var check = (Element.getBoundingClientRect().bottom - window.innerHeight <= 0) ? true : false;
  if (check) { console.log("You're at the bottom!"); }
};
Coldark
la source
2
const handleScroll = () => {
    if (Math.round(window.scrollY + window.innerHeight) >= Math.round(document.body.scrollHeight)) {
        onScroll();
    }
};

Ce code a également fonctionné pour moi dans Firefox et IE.

Arokia Prabha
la source
1

Utilisation defaultViewet documentElementavec un extrait de code fonctionnel intégré:

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
la source
1

Vous pouvez vérifier si le résultat combiné de la hauteur de la fenêtre et du haut du défilement est plus grand que celui du corps

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

Oussama Essamadi
la source
0

J'ai dû trouver un moyen (en Java) de faire défiler systématiquement vers le bas à la recherche d'un composant pour lequel je ne connaissais pas le bon XPath (longue histoire, alors jouez). Comme je viens de le dire, j'avais besoin de faire défiler vers le bas tout en recherchant un composant et de m'arrêter soit lorsque le composant a été trouvé, soit au bas de la page a été atteint.

L'extrait de code suivant contrôle le défilement vers le bas de la page:

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

À propos, la fenêtre est agrandie avant que cet extrait de code ne soit exécuté.

hfontanez
la source
0

La réponse acceptée n'a pas fonctionné pour moi. Cela a fait:

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
la source
0

J'ai trouvé deux solutions qui ont fonctionné pour moi:

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

Et l'autre:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + window.pageYOffset ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })
PJately
la source
Je pense que vous avez échangé le terme haut et bas. Votre solution s'est déclenchée étant au sommet :-)
m3nda
Hey @ m3nda, de quelle solution parlez-vous? Les deux semblent tirer au fond pour moi ...
PJately
J'ai essayé les deux et j'ai été déclenché en haut de la page (contenu supérieur), en face du bas (lorsque vous avez fait défiler la page complète jusqu'à la fin). J'ai vérifié deux fois cela dans Chrome et Firefox. Btw, la solution de @Ifeanyi Amadi a fonctionné comme prévu. Cordialement.
m3nda