ChatGPT解决这个技术问题 Extra ChatGPT

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?


D
Dr.Molle

There are some properties/methods you can use:

$().scrollTop()//how much has been scrolled
$().innerHeight()// inner height of the element
DOMElement.scrollHeight//height of the content of the element

So you can take the sum of the first two properties, and when it equals to the last property, you've reached the end:

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

http://jsfiddle.net/doktormolle/w7X9N/

Edit: I've updated 'bind' to 'on' as per:

As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document.


It will do the binding when the DOM is ready to be sure that the #flux-element is already available.
you should update you answer using ON instead of bind, bind is deprecated in favor of On
Note: When a user is using zoom levels on their browser, this may not work. Zoom causes innerHeight() to report decimals. In the case of a user zooming out, the sum of scrollTop() and innerHeight() will always be at least a fraction short of scrollHeight. I ended up adding a buffer zone of 20px. The resulting conditional was if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20) where el equals $(this).
This is the best answer ever that worked very well for me. Thanks
It's not working anymore, Can you please confirm that why it's not working, Thanks
C
Codler

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.


thank you for this but how can I make the div animate when it reach the bottom of that div? also when you scroll up detect the top of that div then animate also. Just like here on this website lazada.com.ph/apple the sidebar behavior Hope you can help me :)
It works like a magic but the problem it that the alert is executed two times so if you have a call of a function inside it will be executed two times
@1616 I have a variable var running = false declared before this. Inside the conditional, I check if(!running) { running = true; // and continue logic } This way it's only called once! When the AJAX completes, set running = false;
It's about window, but question is about div.
l
lukashambsch

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
}

This is the solution you're looking for if you're not using jQuery.
There is the event handler?
@AlexanderVolkov onscroll is the related event.
A
Alexander Millar

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


R
Ricardo Rivas

this worked for me though

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

M
Mhd Louay Al-osh

In simple DOM usage you can check the condition

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

if true then you have reached the end.


G
Goose

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.


C
Community

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

A
Akshay Hegde

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

$(function() { /* this is only for demonstration purpose */ var t = $('.posts').html(), c = 1, scroll_enabled = true; function load_ajax() { /* call ajax here... on success enable scroll */ $('.posts').append('

' + (++c) + '

' + t); /*again enable loading on scroll... */ scroll_enabled = true; } $(window).bind('scroll', function() { if (scroll_enabled) { /* if 90% scrolled */ if($(window).scrollTop() >= ($('.posts').offset().top + $('.posts').outerHeight()-window.innerHeight)*0.9) { /* load ajax content */ scroll_enabled = false; load_ajax(); } } }); }); h4 { color: red; font-size: 36px; background-color: yellow; }
Lorem ipsum dolor sit amet Consectetuer augue nibh lacus at
Pretium Donec felis dolor penatibus
Phasellus consequat Vivamus dui lacinia
Ornare nonummy laoreet lacus Donec
Ut ut libero Curabitur id
Dui pretium hendrerit sapien Pellentesque
Lorem ipsum dolor sit amet
Consectetuer augue nibh lacus at
Pretium Donec felis dolor penatibus
Phasellus consequat Vivamus dui lacinia
Ornare nonummy laoreet lacus Donec
Ut ut libero Curabitur id
Dui pretium hendrerit sapien Pellentesque
Lorem ipsum dolor sit amet
Consectetuer augue nibh lacus at
Pretium Donec felis dolor penatibus
Phasellus consequat Vivamus dui lacinia
Ornare nonummy laoreet lacus Donec
Ut ut libero Curabitur id
Dui pretium hendrerit sapien Pellentesque
Lorem ipsum dolor sit amet
Consectetuer augue nibh lacus at
Pretium Donec felis dolor penatibus
Phasellus consequat Vivamus dui lacinia
Ornare nonummy laoreet lacus Donec
Ut ut libero Curabitur id
Dui pretium hendrerit sapien Pellentesque


J
John Ostrowick

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

?>

-1 because generating javascript+css code from php is bad practice (hard to maintain, no reusability, no website optimizations etc). Furthermore as pointed out by @Alexander Millar the 10px offset can be fixed by taking padding in to account. Anyone considering using this code should think twice...
S
Starwave

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


I
Israel Chapa

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>

L
Liad Livnat

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

T
Tim Diekmann
$(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.


T
ThisIsWilliam

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 ///
}

e
eylay

none of the answers worked for me, this one did:

$(window).on('scroll', function() {
    if ($(window).scrollTop() >= $('#flux').offset().top + $('#flux').outerHeight() - window.innerHeight) {
        alert('You reached the end of the DIV');
    }
});