Javascript: como detectar se a janela do navegador é rolada para baixo?


187

Preciso detectar se um usuário está rolado até o final de uma página. Se eles estiverem na parte inferior da página, quando eu adicionar novo conteúdo à parte inferior, rolarei automaticamente para a nova parte inferior. Se eles não estiverem na parte inferior, eles estão lendo o conteúdo anterior mais alto na página, então eu não quero rolar automaticamente eles, pois eles querem ficar onde estão.

Como posso detectar se um usuário está rolado para a parte inferior da página ou se ele rolou mais alto na página?


1
Este é trabalhado em Angular 6 -> stackoverflow.com/a/42547136/621951
— Günay Gültekin 11/11

Respostas:


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

Ver demonstração


29
Não funciona quando os elementos html / corpo estão definidos para 100% (de modo que o corpo preenche toda a altura do visor)
— Grodriguez

5
Use em document.documentElement.scrollTopvez de window.scrollYpara o IE. Não tenho certeza de quais versões, se houver, do IE suportam window.scrollY.
— Batandwa

3
Não funciona no Chromium versão 47.0.2526.73 Criada no Ubuntu 14.04, executando no SO elementar 0.3.2 (64 bits)
— K - A toxicidade no SO está aumentando.

9
Usei document.body.scrollHeight em vez de offsetHeight (no meu caso, offsetHeight era sempre menor que a window.innerHeight)
— Oliver

1
@KarlMorrison, você pode tentar a resposta premiada (por @Dekel) com o seu navegador?
— Basj

115

Código atualizado para todos os principais navegadores de suporte (incluindo IE10 e IE11)

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

O problema com a resposta atualmente aceita é que window.scrollYnão está disponível no IE.

Aqui está uma citação de mdn sobre o scrollY:

Para compatibilidade entre navegadores, use window.pageYOffset em vez de window.scrollY.

E um trecho de trabalho:

Nota para mac

Com base no comentário de @ Raphaël, houve um problema no mac devido a um pequeno deslocamento.
A seguinte condição atualizada funciona:

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

Não tive a chance de testá-lo mais, se alguém puder comentar sobre esse problema específico, será ótimo.


Trabalho confirmado no FF, Chrome, IE10, Chrome para Android. Obrigado @Dekel!
— Basj

2
Por estranho que pareça, apenas no meu navegador tenho 1 px e, portanto, a condição não é acionada. Não sei por que, tive que adicionar alguns px extras para fazê-lo funcionar.
— Sharjeel Ahmed

3
em computadores Mac, a condição abaixo não é atendida por causa de um pequeno deslocamento (~ 1px), atualizamos a condição da seguinte maneira:(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
— Raphaël

4
thx @Dekel! na verdade, descobrimos que window.pageYOffset é um flutuador no mac. Nossa solução final é (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
— Raphaël

2
Não funciona nos casos em que o corpo possui um estilo que define a altura para 100%
— raRaRa

56

A resposta aceita não funcionou para mim. Isso fez:

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 você deseja oferecer suporte a navegadores mais antigos (IE9), use o alias window.pageYOffsetque possui um suporte um pouco melhor.


1
não funciona no IE10 / 11. Verifique a resposta de Dekel ( stackoverflow.com/questions/9439725/… ) para obter suporte ao IE. Trabalhou para mim #
— Herr_Schwabullek

As outras respostas acionavam o console.log () toda vez que eu rolava, não apenas quando estava na parte inferior da página. Esta resposta funcionou para mim no Chrome.
— Defcronyke

Se você se livrar do window.scrollY, que não funciona em ie ou edge, esta é uma resposta decente. Substitua por: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
— colemerrick

21

Eu estava procurando uma resposta, mas não encontrei uma exata. Aqui está uma solução javascript pura que funciona com o Firefox, IE e Chrome mais recentes no momento desta resposta:

// 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
Isso quase funcionou para mim, mas eu tinha que usar ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)em vez de apenas document.body.scrollHeightpara a conta para os casos em html / corpo estão definidos para height: 100%
— Grodriguez

1
@Grodriguez Obrigado pela informação! Pode ser útil para nós no futuro! :-)
— pasztorpisti 23/10

15

Isso funciona

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 você deseja oferecer suporte a navegadores mais antigos (IE9), substitua window.scrollY por window.pageYOffset


1
este trabalho reage em 2019. trabalha com corpo a 100% de altura, vale a pena com html 100% de altura. trabalhe com chrome, safari, firefox, edge.
— angry kiwi

Apenas uma observação: a nomeação deve ser alterada - as variáveis ​​devem ser alteradas. Como scrollHeight mostra a altura total da página e totalHeight mostra o ponto de rolagem atual, é um pouco confuso.
— Vladimir Marton

4

Eu apenas comecei a olhar para isso e as respostas aqui me ajudaram, então obrigado por isso. Expandi um pouco para que o código esteja seguro desde o IE7:

Espero que isso seja útil para alguém.

Aqui, tem um 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>

Tipo de obras. Mas não é muito preciso. Ele considera que ele é rolado para a parte inferior desde que você esteja a cerca de 16px da parte inferior.
— Peter Hall

4

Se você estiver configurando height: 100%algum contêiner <div id="wrapper">, o seguinte código funcionará (testado no 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");
    }
};

Esta resposta irá corrigir casos extremos, porque pageYOffseté doubleenquanto innerHeighte offsetHeightsãolong , portanto, quando o navegador fornece as informações, você pode ter um pixel curto. Por exemplo: na parte inferior da página, temos

verdade window.innerHeight = 10.2

verdade window.pageYOffset = 5.4

verdade document.body.offsetHeight = 15.6

Nosso cálculo passa a ser: 10 + 5,4> = 16, o que é falso

Para consertar isso, podemos fazer Math.ceilo pageYOffsetvalor.

Espero que ajude.


3

se você ama jquery

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

E quem não ama jQuery ...
— Josh Habdas

2
@JoshHabdas browsers
— Toni Michel Caubet

2

Você pode ver o infinito pergaminho do jquery:

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

Parece que ele faz o que você está pedindo, supondo que você esteja disposto a usar a biblioteca jquery e não esperando um método JS puro e estrito.


2
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
— Bobthedeveloper 20/05

@Hatsjoem Ele está vinculando a um plugin. Quais são exatamente as "partes essenciais" que devem ser copiadas? Quem se importa se a resposta "se tornar inválida se a página vinculada mudar"? Se o link for quebrado, significa que o plug-in foi descontinuado e não existe mais - mesmo se você adicionar mais informações à resposta, ele ainda será inválido. Caramba, as respostas somente de links não são necessariamente ruins.
— Dcastro 20/05

@Hatsjoem Além disso, de meta : "Quando a biblioteca referenciada está em um local conhecido e estável, esse tipo de resposta geralmente é ruim, mas ainda assim : diz" use this ".
— Dcastro 20/05

Além disso, o Google provavelmente ainda existirá se a rolagem infinita alterar esse URL. O objetivo é usar esse plug-in, portanto, se o link acabar, basta pesquisar no Google jquery rolagem infinita. Você provavelmente encontrará o que precisa.
— Kai Qing

2

Surpreendentemente, nenhuma das soluções funcionou para mim. Eu acho que é porque eu cssestava bagunçado e bodynão envolvia todo o conteúdo ao usá-lo height: 100%(ainda não sei por que). No entanto, ao procurar uma solução, encontrei algo bem ... basicamente o mesmo, mas talvez valha a pena olhar - sou iniciante em programação, desculpe se está fazendo o mesmo mais devagar, tem menos suporte ou algo do tipo aquele...

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 uma perspectiva diferente. Mas a resposta aceita é melhor, com certeza
— Zihan Zhang

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

Este código funcionou para mim no Firefox e IE também.


1

Usando defaultViewe documentElementcom o snippet de código funcional incorporado:

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

Você pode verificar se o resultado combinado da altura da janela e da parte superior da rolagem é maior que o do corpo

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


0

Eu tive que criar uma maneira (em Java) de rolar sistematicamente para baixo, procurando por um componente para o qual eu não conhecia o XPath correto (longa história, então apenas continue). Como acabei de afirmar, eu precisava rolar para baixo enquanto procurava por um componente e parar quando o componente foi encontrado ou na parte inferior da página.

O seguinte trecho de código controla a rolagem para baixo na parte inferior da página:

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 propósito, a janela é maximizada antes que esse trecho de código seja executado.


0

A resposta aceita não funcionou para mim. Isso fez:

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

Encontrei duas soluções que funcionaram para mim:

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

E o outro:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + window.pageYOffset ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.