Verifique se um usuário rolou para baixo

668

Estou criando um sistema de paginação (como o Facebook) em que o conteúdo é carregado quando o usuário rola para baixo. Eu imagino que a melhor maneira de fazer isso é descobrir quando o usuário está na parte inferior da página e executar uma consulta ajax para carregar mais postagens.

O único problema é que não sei como verificar se o usuário rolou para a parte inferior da página com o jQuery. Alguma ideia?

Preciso encontrar uma maneira de verificar quando o usuário rolou para a parte inferior da página com o jQuery.

Johnny
fonte
Engraçado, estou tentando descobrir qual função está sendo chamada quando rolar para o final, para que possa bloquear esse "recurso" irritante.
endolith
Para uma solução React.js, este link pode ajudar: stackoverflow.com/a/53158893/4265546
raksheetbhat

Respostas:

1024

Use o .scroll()evento windowcomo este:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() == $(document).height()) {
       alert("bottom!");
   }
});

Você pode testá-lo aqui , isso leva a rolagem superior da janela; portanto, quanto é rolada para baixo, adiciona a altura da janela visível e verifica se isso é igual à altura do conteúdo geral ( document). Se você quiser verificar se o usuário está perto da parte inferior, seria algo como isto:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       alert("near bottom!");
   }
});

Você pode testar essa versão aqui , basta ajustá-la 100para qualquer pixel da parte inferior em que você deseja acionar.

Nick Craver
fonte
32
Como sempre, você chega lá antes de mim. De qualquer forma, para o OP, se você tiver um contêiner de postagens, use seu ID em vez de "window". Além disso, convém alterar o último .height () para scrollHeight
Christian
4
O Firefox chama alerta ("bottom!"); muitas vezes (funciona bem com o Chrome e Safari)
Marco Matarazzi
3
é meio buggy, se você fizer um em console.log()vez de alertar, às vezes repete o comando.
Jürgen Paul
19
Combinação @KevinVella Vella boa é usar este com _.debounce () em sublinhado utilidade para impedir que ele disparar até utilizador parou rolagem - underscorejs.org/#debounce -
JohnnyFaldo
3
@NickCraver existe alguma implementação js pura disponível?
Dewsworld
116

A resposta de Nick Craver funciona bem, poupando a questão de que o valor $(document).height()varia de acordo com o navegador.

Para fazê-lo funcionar em todos os navegadores, use esta função de James Padolsey :

function getDocHeight() {
    var D = document;
    return Math.max(
        D.body.scrollHeight, D.documentElement.scrollHeight,
        D.body.offsetHeight, D.documentElement.offsetHeight,
        D.body.clientHeight, D.documentElement.clientHeight
    );
}

no lugar de $(document).height(), para que o código final seja:

$(window).scroll(function() {
       if($(window).scrollTop() + $(window).height() == getDocHeight()) {
           alert("bottom!");
       }
   });
Miles O'Keefe
fonte
6
Ele atualizou com uma função de versão ligeiramente compactada getDocHeight () {var D = document; retornar Math.max (D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight); }
Drew
que me avisa quando chego ao topo, não ao fundo (Chrome).
Damien Roche
Talvez seja melhor usá-lo em minvez de max, especialmente se houver uma margem, para evitar impedir acidentalmente o usuário de rolar para o que você acha que é a parte inferior da página.
Solomon Ucko
104

Não sei exatamente por que isso ainda não foi publicado, mas, de acordo com a documentação do MDN , a maneira mais simples é usar propriedades javascript nativas:

element.scrollHeight - element.scrollTop === element.clientHeight

Retorna true quando você está na parte inferior de qualquer elemento rolável. Então, basta usar javascript:

element.addEventListener('scroll', function(event)
{
    var element = event.target;
    if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        console.log('scrolled');
    }
});

scrollHeighttem amplo apoio em navegadores, do IE 8 para ser mais preciso, ao mesmo tempo clientHeighte scrollTopsão ambos suportados por todos. Mesmo ie 6. Isso deve ser seguro para vários navegadores.

Félix Gagnon-Grenier
fonte
1
Observe que em algumas situações isso pode não ser o caso. O Firefox 47 relata um cliente de área de textoHeight como 239, enquanto a equação acima fornece 253 quando rolada para baixo. Talvez estofamento / borda ou algo está afetando isso? De qualquer forma, adicionar algum espaço de manobra não faria mal, como var isAtBottom = ( logField.scrollHeight - logField.scrollTop <= logField.clientHeight + 50 );. Isso é útil para rolar automaticamente um campo se já estiver na parte inferior (para que o usuário possa examinar manualmente uma parte específica de um log em tempo real sem perder seu lugar, etc.).
Beejor 19/08/16
Eu acrescentaria que é possível retornar falsos negativos, pois um lado pode retornar um pequeno decimal, enquanto o outro lado retorna um número inteiro (por exemplo, 200.181819304947e 200). Eu adicionei um Math.floor()para ajudar a lidar com isso, mas não sei o quão confiável isso será.
217 Hanna
1
Para mim, isso não funciona em vários navegadores. Eu obtenho resultados completamente diferentes no chrome em comparação com o firefox.
Tadej
1
Eu tentei isso no elemento <body>, e isso é acionado quando o navegador é rolado para o topo, não para o fundo.
precisa
10
Math.abs(element.scrollHeight - element.scrollTop - element.clientHeight) <= 3.0(substitua 3.0 por qualquer tolerância de pixel que considere apropriada para suas circunstâncias). Este é o caminho a percorrer porque (A) clientHeight, scrollTope clientHeightsão todos arredondados, o que poderia levar a um erro de 3px se todos os alinhamentos, (B) 3 pixels não estiverem visíveis para o usuário, para que ele possa pensar que algo está errado com seu site. quando eles "pensam" que estão na parte inferior da página, quando na verdade não estão, e (C) certos dispositivos (especialmente os sem mouse) podem ter um comportamento estranho ao rolar a tela.
Jack Giffin
50

Para aqueles que usam a solução de Nick e recebem alertas / eventos repetidos, é possível adicionar uma linha de código acima do exemplo de alerta:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       $(window).unbind('scroll');
       alert("near bottom!");
   }
});

Isso significa que o código será acionado apenas na primeira vez em que você estiver a 100px da parte inferior do documento. Ele não será repetido se você rolar para cima e para baixo, o que pode ou não ser útil, dependendo do uso do código de Nick.

Tim Carr
fonte
1
Eu teria acabado de comentar e dizer onde é que essa linha de código é relevante para a resposta de outra pessoa, mas +1 para a intenção!
Nate-Wilkins
Desculpe, não consegui (e ainda não consigo) ver como adicionar um comentário à resposta (como posso aqui)?
Tim Carr
Sim, novos usuários não podem adicionar um comentário às postagens, a menos que você obtenha mais representantes.
Nate-Wilkins
Fora o primeiro, se você puder colocar um diferente se isso testar se a alteração que você deseja que o script faça exista, digamos que uma classe tenha sido aplicada a uma div. Isso tornaria o segundo aninhado se não executado, se já tiver sido executado.
1934286
como posso selecionar o div div particular em vez da janela inteira?
James Smith
40

Além da excelente resposta aceita por Nick Craver, você pode controlar o evento de rolagem para que não seja acionado com tanta frequência, aumentando assim o desempenho do navegador :

var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);

$document.ready(function () {

    $window
        .off('scroll', ScrollHandler)
        .on('scroll', ScrollHandler);

});

function ScrollHandler(e) {
    //throttle event:
    clearTimeout(_throttleTimer);
    _throttleTimer = setTimeout(function () {
        console.log('scroll');

        //do work
        if ($window.scrollTop() + $window.height() > $document.height() - 100) {
            alert("near bottom!");
        }

    }, _throttleDelay);
}
George Filippakos
fonte
Provavelmente, deve-se destacar que isso requer Underscore.js: underscorejs.org . É um ponto muito bom, no entanto. O evento de rolagem sempre deve ser sempre otimizado para evitar problemas sérios de desempenho.
Jude Osborn
Talvez seja só eu e possa usar alguns testes de referência, mas não gosto da ideia de chamar clearTimeout e setTimeout em todos os eventos de rolagem. Eu emitiria 1 setTimeout e adicionaria alguns guardas nesse manipulador. Provavelmente é apenas uma micro-otimização (se houver).
Careta de desespero
Esta é uma adição muito legal! Eu posso pensar em mais uma melhoria. Atualmente, a função que verifica a altura não será executada se o usuário continuar a rolar. Se isso for um problema (por exemplo, você deseja ativar a função quando o usuário rolou até a metade, independentemente de continuar rolando), você pode facilmente garantir que a função seja realmente chamada enquanto ainda proíbe várias chamadas durante o intervalo escolhido. Aqui está uma essência para mostrá-lo. gist.github.com/datacarl/7029558
datacarl
O que? Invocar uma carga de máquinas para impedir um cálculo simples? Eu não vejo como isso é mais eficiente, tudo #
Rambatino 26/11
37

A resposta de Nick Craver precisa ser ligeiramente modificada para funcionar no iOS 6 Safari Mobile e deve ser:

$(window).scroll(function() {
   if($(window).scrollTop() + window.innerHeight == $(document).height()) {
       alert("bottom!");
   }
});

Alterar (janela) .height $ () para window.innerHeight deve ser feito porque quando a barra de endereços está escondido um 60px adicionais são adicionados à altura da janela, mas usando $(window).height()que não refletem essa mudança, enquanto estiver usando window.innerHeighto faz.

Nota : A window.innerHeightpropriedade também inclui a altura da barra de rolagem horizontal (se for renderizada), diferente da $(window).height()que não incluirá a altura da barra de rolagem horizontal. Isso não é um problema no Mobile Safari, mas pode causar comportamento inesperado em outros navegadores ou versões futuras do Mobile Safari. Alterar ==para >=poderia corrigir isso nos casos de uso mais comuns.

Leia mais sobre a window.innerHeightpropriedade aqui

Yosi
fonte
window.innerHeight fazia mais sentido para o que eu estava tentando realizar obrigado!
Amir5000
Como obter a altura restante após a rolagem?
OPV
21

Aqui está uma abordagem bastante simples

const didScrollToBottom = elm.scrollTop + elm.clientHeight == elm.scrollHeight

Exemplo

elm.onscroll = function() {
    if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) {
        // User has scrolled to the bottom of the element
    }
}

Onde elmé um elemento recuperado de ie document.getElementById.

Frederik Witte
fonte
17

Aqui está um pedaço de código que o ajudará a depurar seu código, testei as respostas acima e as achei com erros. Eu testei o seguinte no Chrome, IE, Firefox, IPad (Safari). Não tenho nenhum outro instalado para testar ...

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var winElement = $(window)[0];

         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
            alert('bottom');
         }
      });
   });
</script>

Pode haver uma solução mais simples, mas parei no ponto em que FUNCIONA

Se você ainda estiver tendo problemas com algum navegador não autorizado, aqui está um código para ajudá-lo a depurar:

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var details = "";
         details += '<b>Document</b><br />';
         details += 'clientHeight:' + docElement.clientHeight + '<br />';
         details += 'clientTop:' + docElement.clientTop + '<br />';
         details += 'offsetHeight:' + docElement.offsetHeight + '<br />';
         details += 'offsetParent:' + (docElement.offsetParent == null) + '<br />';
         details += 'scrollHeight:' + docElement.scrollHeight + '<br />';
         details += 'scrollTop:' + docElement.scrollTop + '<br />';

         var winElement = $(window)[0];
         details += '<b>Window</b><br />';
         details += 'innerHeight:' + winElement.innerHeight + '<br />';
         details += 'outerHeight:' + winElement.outerHeight + '<br />';
         details += 'pageYOffset:' + winElement.pageYOffset + '<br />';
         details += 'screenTop:' + winElement.screenTop + '<br />';
         details += 'screenY:' + winElement.screenY + '<br />';
         details += 'scrollY:' + winElement.scrollY + '<br />';

         details += '<b>End of page</b><br />';
         details += 'Test:' + (docElement.scrollHeight - winElement.innerHeight) + '=' + winElement.pageYOffset + '<br />';
         details += 'End of Page? ';
         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
             details += 'YES';
         } else {
             details += 'NO';
         }

         $('#test').html(details);
      });
   });
</script>
<div id="test" style="position: fixed; left:0; top: 0; z-index: 9999; background-color: #FFFFFF;">

Espero que isso poupe tempo a alguém.

Talon
fonte
Melhor resposta para Vanilla js, sem solução jQuery. Usevar docElement = document.documentElement; var winElement = window
jperelli
Isso em 2019. Em vez de winElement.pageYOffsetvocê também pode usar winElement.scrollY.
Noel Abrahams
15

Por favor, verifique esta resposta

 window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
       console.log("bottom");
    }
};

Você pode fazer footerHeight - document.body.offsetHeightpara ver se você está perto do rodapé ou alcançou o rodapé

Junaid Qadir
fonte
12
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

Ele calcula a barra de rolagem da distância até a parte inferior do elemento. Igual a 0, se a barra de rolagem chegou ao fundo.

Vasyl Gutnyk
fonte
1
Fiz o seguinte e trabalhei na perfeição. Obrigado. var shouldScroll = (elem.scrollHeight - elem.scrollTop - elem.clientHeight) == 0;
jiminssy
11

Estes são meus dois centavos:

$('#container_element').scroll( function(){
        console.log($(this).scrollTop()+' + '+ $(this).height()+' = '+ ($(this).scrollTop() + $(this).height())   +' _ '+ $(this)[0].scrollHeight  );
        if($(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight){
            console.log('bottom found');
        }
    });
ddanone
fonte
Tentei usar sua solução, ela funciona bem, mas nos casos em que o elemento possui preenchimento - não funciona porque calcula a altura pura do elemento, sem incluir o preenchimento, para resolver isso, mudei isso $(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight=>$(this).scrollTop() + $(this).outerHeight(true) >= $(this)[0].scrollHeight
Taras Chernata
6

JS puro com cross-browser e depuração ( desempenho muito bom )

var CheckIfScrollBottom = debouncer(function() {
    if(getDocHeight() == getScrollXY()[1] + window.innerHeight) {
       console.log('Bottom!');
    }
},500);

document.addEventListener('scroll',CheckIfScrollBottom);

function debouncer(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}
function getScrollXY(){var a=0,b=0;return"number"==typeof window.pageYOffset?(b=window.pageYOffset,a=window.pageXOffset):document.body&&(document.body.scrollLeft||document.body.scrollTop)?(b=document.body.scrollTop,a=document.body.scrollLeft):document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)&&(b=document.documentElement.scrollTop,a=document.documentElement.scrollLeft),[a,b]}
function getDocHeight(){var a=document;return Math.max(a.body.scrollHeight,a.documentElement.scrollHeight,a.body.offsetHeight,a.documentElement.offsetHeight,a.body.clientHeight,a.documentElement.clientHeight)}

Demonstração: http://jsbin.com/geherovena/edit?js,output

PS: Debouncer, getScrollXY, getDocHeightnão escrita por mim

Eu apenas mostro como funciona, e como farei

l2aelba
fonte
Perfeito. Testado no Firefox e Chrome
Erlisar Vasquez 23/11
Eu recebo o seguinte erro: Esperado 3 argumentos, mas obtive 2. Um argumento 'c' não foi fornecido.
Sober
6

Minha solução em js simples:

let el=document.getElementById('el');
el.addEventListener('scroll', function(e) {
    if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) {
        alert('Bottom');
    }
});
#el{
  width:400px;
  height:100px;
  overflow-y:scroll;
}
<div id="el">
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>

Bakos Bence
fonte
4

Tente isso para a condição de correspondência se rolar para a extremidade inferior

if ($(this)[0].scrollHeight - $(this).scrollTop() == 
    $(this).outerHeight()) {

    //code for your custom logic

}
Hiren Patel
fonte
3

Nick responde bem, mas você terá funções que se repetem durante a rolagem ou não funcionarão se o usuário tiver a janela ampliada. Eu vim com uma correção fácil apenas math.round a primeira altura e funciona da mesma forma que assumido.

    if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
    loadPagination();
    $(".go-up").css("display","block").show("slow");
}
Florin Andrei
fonte
3

Você pode tentar o seguinte código,

$("#dashboard-scroll").scroll(function(){
    var ele = document.getElementById('dashboard-scroll');
    if(ele.scrollHeight - ele.scrollTop === ele.clientHeight){
       console.log('at the bottom of the scroll');
    }
});
Shahrukh Anwar
fonte
2

Isso fornece resultados precisos, ao verificar um elemento rolável (ou seja, não window):

// `element` is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
    // Element scrolled to bottom

offsetHeightdeve fornecer a altura visível real de um elemento (incluindo preenchimento, margem e barras de rolagem) e scrollHeighté a altura inteira de um elemento, incluindo áreas invisíveis (excedidas).

jQuery's .outerHeight()deve dar resultado semelhante ao JS de .offsetHeight- a documentação em MDN para offsetHeightse sabe sobre o seu apoio cross-browser. Para cobrir mais opções, isso é mais completo:

var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if  ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
   // scrolled to bottom
}
Yuval A.
fonte
tente Math.floor(element.scrollTop) === element.scrollHeight - element.offsetHeightno caso do scrollTop ser um decimal que não funcionará semMath.floor()
Michail Michailidis 4/03
1

Todas essas soluções não funcionam para mim no Firefox e Chrome, então eu uso funções personalizadas de Miles O'Keefe e meder omuraliev assim:

function getDocHeight()
{
    var D = document;
    return Math.max(
        D.body.scrollHeight, D.documentElement.scrollHeight,
        D.body.offsetHeight, D.documentElement.offsetHeight,
        D.body.clientHeight, D.documentElement.clientHeight
    );
}

function getWindowSize()
{
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  return [myWidth, myHeight];
}

$(window).scroll(function()
{
    if($(window).scrollTop() + getWindowSize()[1] == getDocHeight())
    {
        alert("bottom!");
    }
});
hayj
fonte
1

Aqui estão meus dois centavos, pois a resposta aceita não funcionou para mim.

var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;
Vince Panuccio
fonte
1

Em vez de ouvir o evento de rolagem, usar o Intersection Observer é barato para verificar se o último elemento estava visível na janela de exibição (ou seja, o usuário médio foi rolado para baixo). Também suportou o IE7 com o polyfill .

var observer = new IntersectionObserver(function(entries){
   if(entries[0].isIntersecting === true)
      console.log("Scrolled to the bottom");
   else
      console.log("Not on the bottom");
}, {
   root:document.querySelector('#scrollContainer'),
   threshold:1 // Trigger only when whole element was visible
});

observer.observe(document.querySelector('#scrollContainer').lastElementChild);
#scrollContainer{
  height: 100px;
  overflow: hidden scroll;
}
<div id="scrollContainer">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div>
  <div>Item 6</div>
  <div>Item 7</div>
  <div>Item 8</div>
  <div>Item 9</div>
  <div>Item 10</div>
</div>

StefansArya
fonte
O problema com o Intersection Observer é que, se a janela inicial for relativamente pequena (por exemplo, layout básico antes de buscar imagens sem barra de rolagem), o retorno de chamada do observador será acionado imediatamente. O ouvinte de rolagem aguarda a rolagem de uma pessoa. E a barra de rolagem não aparecerá antes que o primeiro lote de imagens e etc. seja buscado. Portanto, o Intersection Observer não é tudo em uma solução.
Aleks 12/03
@Aleks Você pode chamar o .observe(...)ouvinte de um evento como quando o usuário passa / toca no contêiner de rolagem para que ele não seja acionado imediatamente.
StefansArya 12/03
0

Deixe-me mostrar approch sem JQuery. Função JS simples:

function isVisible(elem) {
  var coords = elem.getBoundingClientRect();
  var topVisible = coords.top > 0 && coords.top < 0;
  var bottomVisible = coords.bottom < shift && coords.bottom > 0;
  return topVisible || bottomVisible;
}

Exemplo curto de como usá-lo:

var img = document.getElementById("pic1");
    if (isVisible(img)) { img.style.opacity = "1.00";  }
Alexei Zababurin
fonte
5
Isso não responde à pergunta. A questão era como detectar que os usuários rolaram a janela até o fim. Seu código está verificando se um elemento específico está em exibição.
Peter Hall
0

Usei o @ddanone answerear e adicionei a chamada Ajax.

$('#mydiv').on('scroll', function(){
  function infiniScroll(this);
});

function infiniScroll(mydiv){
console.log($(mydiv).scrollTop()+' + '+ $(mydiv).height()+' = '+ ($(mydiv).scrollTop() + $(mydiv).height())   +' _ '+ $(mydiv)[0].scrollHeight  );

if($(mydiv).scrollTop() + $(mydiv).height() == $(mydiv)[0].scrollHeight){
    console.log('bottom found');
    if(!$.active){ //if there is no ajax call active ( last ajax call waiting for results ) do again my ajax call
        myAjaxCall();
    }
}

}

Henrique C.
fonte
0

Para parar o alerta repetido da resposta de Nick

ScrollActivate();

function ScrollActivate() {
    $(window).on("scroll", function () {
        if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
            $(window).off("scroll");
            alert("near bottom!");
        }
    });
}
Arun Prasad ES
fonte
0

O Google Chrome fornece toda a altura da página, se você ligar $(window).height()

Em vez disso, use window.innerHeightpara recuperar a altura da sua janela. A verificação necessária deve ser:

if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
    console.log("reached bottom!");
}
alierdogan7
fonte
0

Aparentemente, o que funcionou para mim foi 'corpo' e não 'janela' assim:

$('body').scroll(function() {


 if($('body').scrollTop() + $('body').height() == $(document).height()) {
     //alert at buttom
 }
 });

para compatibilidade entre navegadores, use:

  function getheight(){
    var doc = document;
    return  Math.max(
        doc.body.scrollHeight, doc.documentElement.scrollHeight,
        doc.body.offsetHeight, doc.documentElement.offsetHeight,
        doc.body.clientHeight, doc.documentElement.clientHeight

        );
   }

e depois em vez de $ (document) .height () chame a função getheight ()

$('body').scroll(function() {


   if($('body').scrollTop() + $('body').height() == getheight()  ) {
     //alert at bottom
 }
});

para uso próximo ao fundo:

$('body').scroll(function() {


if($('body').scrollTop() + $('body').height() > getheight() -100 ) {
    //alert near bottom
 }
 });
GeniusGeek
fonte