86

I have a div layer with overflow set to scroll.

When scrolled to the bottom of the div, I wanna run a function.


Community
  • 1
  • 1
Zebra
  • 3,858
  • 9
  • 39
  • 52

15 Answers15

143

The accepted answer was fundamentally flawed, it has since been deleted. The correct answer is:

function scrolled(e) {
  if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
    scrolledToBottom(e);
  }
}

Tested this in Firefox, Chrome and Opera. It works.

Bjorn
  • 69,215
  • 39
  • 136
  • 164
  • Can you let us know why it's flawed? – SpoonMeiser Feb 15 '11 at 11:36
  • 7
    Because it doesn't detect scroll end at all, it detects when when the portion of the page scrolled upward and height of the containing div are the same! Say you have have twice the content to scroll through than the height of the div, once you've reached the very end, the scrollTop value will be twice the size than the container's offsetHeight. The accepted answer checks to see if these are equal, and it will not detect the end. My solution checks to see if the scrollTop + the container's height is equal to (or greater than, it happens) the entire scrollable area, now that's the bottom! – Bjorn Feb 15 '11 at 15:18
  • 5
    @Alex `window.location.href = 'http://newurl.com';` or `window.open('http://newurl.com');` + the code above. – Bjorn Apr 08 '11 at 19:09
  • Tips is you can't get this to work is to use this CSS: `html, body: { height:100% }`. – Pylinux Jan 26 '15 at 11:54
  • 1
    Can you please suggest how can I check the same for horizontal scrollbar in a div? – Jay Shukla Apr 17 '15 at 10:35
  • I haven't tried it but I imagine you could just use offsetWidth, scrollWidth and scrollLeft and do something similar. – Bjorn Apr 17 '15 at 17:26
  • There are instances where ```myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight``` will always return false. In that case use ```Math.round(myDiv.offsetHeight + myDiv.scrollTop) >= myDiv.scrollHeight``` – cguy Nov 13 '22 at 13:27
9
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight)
{
//your code here
}

I too searched it and even after checking all comments here and more, this is the solution to check if reached the bottom or not.

Moshe Cohen
  • 91
  • 1
  • 2
7

I could not get either of the above answers to work so here is a third option that works for me! (This is used with jQuery)

if (($(window).innerHeight() + $(window).scrollTop()) >= $("body").height()) {
    //do stuff
}

Hope this helps anyone!

just_user
  • 11,769
  • 19
  • 90
  • 135
6

OK Here is a Good And Proper Solution

You have a Div call with an id="myDiv"

so the function goes.

function GetScrollerEndPoint()
{
   var scrollHeight = $("#myDiv").prop('scrollHeight');
   var divHeight = $("#myDiv").height();
   var scrollerEndPoint = scrollHeight - divHeight;

   var divScrollerTop =  $("#myDiv").scrollTop();
   if(divScrollerTop === scrollerEndPoint)
   {
       //Your Code 
       //The Div scroller has reached the bottom
   }
}
Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
maxspan
  • 13,326
  • 15
  • 75
  • 104
4

This worked for me:

$(window).scroll(function() {
  buffer = 40 // # of pixels from bottom of scroll to fire your function. Can be 0
  if ($(".myDiv").prop('scrollHeight') - $(".myDiv").scrollTop() <= $(".myDiv").height() + buffer )   {
    doThing();
  }
});

Must use jQuery 1.6 or higher

AlexQueue
  • 6,353
  • 5
  • 35
  • 44
3

I found an alternative that works.

None of these answers worked for me (currently testing in FireFox 22.0), and after a lot of research I found, what seems to be, a much cleaner and straight forward solution.

Implemented solution:

function IsScrollbarAtBottom() {
    var documentHeight = $(document).height();
    var scrollDifference = $(window).height() + $(window).scrollTop();
    return (documentHeight == scrollDifference);
}

Resource: http://jquery.10927.n7.nabble.com/How-can-we-find-out-scrollbar-position-has-reached-at-the-bottom-in-js-td145336.html

Regards

Chandler Zwolle
  • 1,635
  • 1
  • 11
  • 8
3

I created a event based solution based on Bjorn Tipling's answer:

(function(doc){
    'use strict';

    window.onscroll = function (event) {
        if (isEndOfElement(doc.body)){
            sendNewEvent('end-of-page-reached');
        }
    };

    function isEndOfElement(element){
        //visible height + pixel scrolled = total height 
        return element.offsetHeight + element.scrollTop >= element.scrollHeight;
    }

    function sendNewEvent(eventName){
        var event = doc.createEvent('Event');
        event.initEvent(eventName, true, true);
        doc.dispatchEvent(event);
    }
}(document));

And you use the event like this:

document.addEventListener('end-of-page-reached', function(){
    console.log('you reached the end of the page');
});

BTW: you need to add this CSS for javascript to know how long the page is

html, body {
    height: 100%;
}

Demo: http://plnkr.co/edit/CCokKfB16iWIMddtWjPC?p=preview

Lior Cohen
  • 8,985
  • 2
  • 29
  • 27
Pylinux
  • 11,278
  • 4
  • 60
  • 67
  • I see now that the OP asked for end of a div and not the end of the page, but I'll leave the answer here in case it helps somebody else. – Pylinux Jan 26 '15 at 12:06
3

There is experimental onscrollend event https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event

For now works only in firefox 109+, if other browsers catch up will be very nice.

Have polyfill for that https://github.com/argyleink/scrollyfills Use like

import "scrollyfills";
...
    scrollContainer.addEventListener(
      "scrollend",
      (ev) => { console.log('scroll END') }
    );

2

This will actually be the correct answer:

function scrolled(event) {
   const container = event.target.body
   const {clientHeight, scrollHeight, scrollY: scrollTop} = container

   if (clientHeight + scrollY >= scrollHeight) {
    scrolledToBottom(event);
   }
}

The reason for using the event is up-to-date data, if you'll use a direct reference to the div you'll get outdated scrollY and will fail to detect the position correctly.

additional way is to wrap it in a setTimeout and wait till the data updates.

ddavidad
  • 839
  • 5
  • 6
1

Take a look at this example: MDN Element.scrollHeight

I recommend that check out this example: stackoverflow.com/a/24815216... which implements a cross-browser handling for the scroll action.

You may use the following snippet:

//attaches the "scroll" event
$(window).scroll(function (e) {
    var target = e.currentTarget,
        scrollTop = target.scrollTop || window.pageYOffset,
        scrollHeight = target.scrollHeight || document.body.scrollHeight;
    if (scrollHeight - scrollTop === $(target).innerHeight()) {
      console.log("► End of scroll");
    }
});
Community
  • 1
  • 1
jherax
  • 5,238
  • 5
  • 38
  • 50
0

Since innerHeight doesn't work in some old IE versions, clientHeight can be used:

$(window).scroll(function (e){
    var body = document.body;    
    //alert (body.clientHeight);
    var scrollTop = this.pageYOffset || body.scrollTop;
    if (body.scrollHeight - scrollTop === parseFloat(body.clientHeight)) {
        loadMoreNews();
    }
});
Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
Rado
  • 1
0

To do the same in React/JSX, here is the snippet.

export const scrolledToEnd = event => {
  const container = event.target;

  if (container.offsetHeight + container.scrollTop >= container.scrollHeight) {
    return true;
  }
  return false;
};

And in your component add

<Component onScroll={scrolledToEnd}>
Vineeth Sai
  • 3,389
  • 7
  • 23
  • 34
0

I found this methode to get the end of the scroll :

let TheBody = document.getElementsByTagName("body"); // I choose the "body" element for my exemple
function OnScrolling(){                             // put this on a scrolling EVENT
let ScrollEnd = TheBody[0].scrollHeight - window.innerHeight; // this is the scroll end Pixel

    if (ScrollEnd.toFixed() == window.scrollY.toFixed()){
        //do stuff 
    }
}
0

Okay now for your DIV or any other element that have a scrolling I found this method on JavaScript :

let D = document.getElementById("D1"); // I gave "D1" as id to my div

    // this one is to calculate the scroll end Pixels
let Calc = D.scrollHeight - D.clientHeight;

function ScrollingInD1() {

    //this one is to calculate the scrolling percent while going through the <div> it can help for "Responsivity"
let percent = (D.scrollTop * 100) / Calc;

    if (D.scrollTop == Calc) {
        // do Stuffs
    }
}
0

This worked for me using NextJS. Hope it helps.

  • Subtract 1px from scrollHeight
function onScroll(e: any) {
    const scroll = e.target.offsetHeight + e.target.scrollTop
    const height = e.target.scrollHeight - 1

    if (scroll >= height){
        console.log("END REACHED")
    }
}

return (
    <div onScroll={onScroll}></div>
)
Kuza Grave
  • 1,256
  • 14
  • 15