[javascript] Detecting when user scrolls to bottom of div with jQuery

I have a div box (called flux) with a variable amount of content inside. This divbox has overflow set to auto.

Now, what I am trying to do, is, when the use scroll to the bottom of this DIV-box, load more content into the page, I know how to do this (load the content) but I don't know how to detect when the user has scrolled to the bottom of the div tag? If I wanted to do it for the entire page, I'd take .scrollTop and subtract that from .height.

But I can't seem to do that here?

I've tried taking .scrollTop from flux, and then wrapping all the content inside a div called inner, but if I take the innerHeight of flux it returns 564px (the div is set to 500 as height) and the height of 'innner' it returns 1064, and the scrolltop, when at the bottom of the div says 564.

What can I do?

This question is related to javascript jquery

The answer is


not sure if it is any help but this is how I do it.

I have an index panel that is larger that the window and I let it scroll until the end this index is reached. Then I fix it in position. The process is reversed once you scroll toward the top of the page.

Regards.

<style type="text/css">
    .fixed_Bot {    
            position: fixed;     
            bottom: 24px;    
        }     
</style>

<script type="text/javascript">
    $(document).ready(function () {
        var sidebarheight = $('#index').height();
        var windowheight = $(window).height();


        $(window).scroll(function () {
            var scrollTop = $(window).scrollTop();

            if (scrollTop >= sidebarheight - windowheight){
                $('#index').addClass('fixed_Bot');
            }
            else {
                $('#index').removeClass('fixed_Bot');
            }                   
        });
    });

</script>

Though this was asked almost 6 years, ago still hot topic in UX design, here is demo snippet if any newbie wanted to use

_x000D_
_x000D_
$(function() {_x000D_
_x000D_
  /* this is only for demonstration purpose */_x000D_
  var t = $('.posts').html(),_x000D_
    c = 1,_x000D_
    scroll_enabled = true;_x000D_
_x000D_
  function load_ajax() {_x000D_
_x000D_
    /* call ajax here... on success enable scroll  */_x000D_
    $('.posts').append('<h4>' + (++c) + ' </h4>' + t);_x000D_
_x000D_
    /*again enable loading on scroll... */_x000D_
    scroll_enabled = true;_x000D_
_x000D_
  }_x000D_
_x000D_
_x000D_
  $(window).bind('scroll', function() {_x000D_
    if (scroll_enabled) {_x000D_
_x000D_
      /* if 90% scrolled */_x000D_
    if($(window).scrollTop() >= ($('.posts').offset().top + $('.posts').outerHeight()-window.innerHeight)*0.9) {_x000D_
_x000D_
        /* load ajax content */_x000D_
        scroll_enabled = false;  _x000D_
        load_ajax();_x000D_
      }_x000D_
_x000D_
    }_x000D_
_x000D_
  });_x000D_
_x000D_
});
_x000D_
h4 {_x000D_
  color: red;_x000D_
  font-size: 36px;_x000D_
  background-color: yellow;_x000D_
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>_x000D_
<div class="posts">_x000D_
  Lorem ipsum dolor sit amet  Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit_x000D_
  sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br>  Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut_x000D_
  libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet_x000D_
  lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque_x000D_
</div>
_x000D_
_x000D_
_x000D_


If you are not using Math.round() function the solution suggested by Dr.Molle will not work in some cases when a browser window has a zoom.

For example $(this).scrollTop() + $(this).innerHeight() = 600

$(this)[0].scrollHeight yields = 599.99998

600 >= 599.99998 fails.

Here is the correct code:

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10)) {
            alert('end reached');
        }
    })
});

You may also add some extra margin pixels if you do not need a strict condition

var margin = 4

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10) - margin) {
            alert('end reached');
        }
    })
});

Guys this is the solution to the zoom issue, it works with all zoom levels, in case you need it:

if ( Math.abs(elem.offset().top) + elem.height() + elem.offset().top >= elem.outerHeight() ) {
                    console.log("bottom");
                    // We're at the bottom!
                }
            });
        }

If you need to use this on a div that has overflow-y as hidden or scroll, something like this may be what you need.

if ($('#element').prop('scrollHeight') - $('#element').scrollTop() <= Math.ceil($('#element').height())) {
    at_bottom = true;
}

I found ceil was needed because prop scrollHeight seems to round, or perhaps some other reason causing this to be off by less than 1.


In simple DOM usage you can check the condition

element.scrollTop + element.clientHeight == element.scrollHeight

if true then you have reached the end.


I have crafted this piece of code that worked for me to detect when I scroll to the end of an element!

let element = $('.element');

if ($(document).scrollTop() > element.offset().top + element.height()) {

     /// do something ///
}

Here's another version.

The key code is function scroller() which takes input as the height of the div containing the scrolling section, using overflow:scroll. It approximates 5px from the top or 10px from the bottom as at the top or bottom. Otherwise it's too sensitive. It seems 10px is about the minimum. You'll see it adds 10 to the div height to get the bottom height. I assume 5px might work, I didn't test extensively. YMMV. scrollHeight returns the height of the inner scrolling area, not the displayed height of the div, which in this case is 400px.

<?php

$scrolling_area_height=400;
echo '
<script type="text/javascript">
          function scroller(ourheight) {
            var ourtop=document.getElementById(\'scrolling_area\').scrollTop;
            if (ourtop > (ourheight-\''.($scrolling_area_height+10).'\')) {
                alert(\'at the bottom; ourtop:\'+ourtop+\' ourheight:\'+ourheight);
            }
            if (ourtop <= (5)) {
                alert(\'Reached the top\');
            }
          }
</script>

<style type="text/css">
.scroller { 
            display:block;
            float:left;
            top:10px;
            left:10px;
            height:'.$scrolling_area_height.';
            border:1px solid red;
            width:200px;
            overflow:scroll; 
        }
</style>

$content="your content here";

<div id="scrolling_area" class="scroller">
onscroll="var ourheight=document.getElementById(\'scrolling_area\').scrollHeight;
        scroller(ourheight);"
        >'.$content.'
</div>';

?>

this worked for me though

$(window).scroll(function() {
  if ($(window).scrollTop() >= (($(document).height() - $(window).height()) - $('#divID').innerHeight())) {
    console.log('div reached');
  }
});

I found a solution that when you scroll your window and end of a div shown from bottom gives you an alert.

$(window).bind('scroll', function() {
    if($(window).scrollTop() >= $('.posts').offset().top + $('.posts').outerHeight() - window.innerHeight) {
        alert('end reached');
    }
});

In this example if you scroll down when div (.posts) finish its give you an alert.


Just an additional note here as I found this when looking for a solution for a fixed div that I want to scroll. For my scenario I found that its preferable to take into account the padding on the div so I can hit the end exactly. So expanding on @Dr.Molle's answer I add the following

$('#flux').bind('scroll', function() {
    var scrollPosition = $(this).scrollTop() + $(this).outerHeight();
    var divTotalHeight = $(this)[0].scrollHeight 
                          + parseInt($(this).css('padding-top'), 10) 
                          + parseInt($(this).css('padding-bottom'), 10)
                          + parseInt($(this).css('border-top-width'), 10)
                          + parseInt($(this).css('border-bottom-width'), 10);

    if( scrollPosition == divTotalHeight )
    {
      alert('end reached');
    }
  });

That'll give you the precise location, including padding and borders


$(window).on("scroll", function() {
    //get height of the (browser) window aka viewport
    var scrollHeight = $(document).height();
    // get height of the document 
    var scrollPosition = $(window).height() + $(window).scrollTop();
    if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
        // code to run when scroll to bottom of the page
    }
});

This is the code on github.


Though the question was asked 5.5 years ago, still it is more than relevant in today's UI/UX context. And I would like to add my two cents.

var element = document.getElementById('flux');
if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        // element is at the end of its scroll, load more content
    }

Source: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Determine_if_an_element_has_been_totally_scrolled

Some elements won't allow you to scroll the full height of the element. In those cases you can use:

var element = docuement.getElementById('flux');
if (element.offsetHeight + element.scrollTop === element.scrollHeight) {
  // element is at the end of its scroll, load more content
}

If anyone gets scrollHeight as undefined, then select elements' 1st subelement: mob_top_menu[0].scrollHeight