检测滚动结束

我有一个 div层与 overflow设置为 scroll

当滚动到 div的底部时,我想运行一个函数。


145119 次浏览

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.

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!

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

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

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

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

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

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

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.

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.

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