I need to detect if a user is scrolled to the bottom of a page. If they are at the bottom of the page, when I add new content to the bottom, I will automatically scroll them
I was searching for an answer but haven't found an exact one. Here is a pure javascript solution that works with latest Firefox, IE and Chrome at the time of this answer:
// document.body.scrollTop alone should do the job but that actually works only in case of Chrome.
// With IE and Firefox it also works sometimes (seemingly with very simple pages where you have
// only a <pre> or something like that) but I don't know when. This hack seems to work always.
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
// Grodriguez's fix for scrollHeight:
// accounting for cases where html/body are set to height:100%
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
// >= is needed because if the horizontal scrollbar is visible then window.innerHeight includes
// it and in that case the left side of the equation is somewhat greater.
var scrolledToBottom = (scrollTop + window.innerHeight) >= scrollHeight;
// As a bonus: how to scroll to the bottom programmatically by keeping the horizontal scrollpos:
// Since window.innerHeight includes the height of the horizontal scrollbar when it is visible
// the correct vertical scrollTop would be
// scrollHeight-window.innerHeight+sizeof(horizontal_scrollbar)
// Since we don't know the visibility/size of the horizontal scrollbar
// we scroll to scrollHeight that exceeds the value of the
// desired scrollTop but it seems to scroll to the bottom with all browsers
// without problems even when the horizontal scrollbar is visible.
var scrollLeft = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft;
window.scrollTo(scrollLeft, scrollHeight);
window.onscroll = function(ev) {
if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
alert("you're at the bottom of the page");
}
};
This Answer will fix edge cases, this is because pageYOffset
is double
while innerHeight
and offsetHeight
are long
, so when the browser gives you the info, you may be a pixel short.
For example: on bottom of the page we have
true window.innerHeight = 10.2
true window.pageYOffset = 5.4
true document.body.offsetHeight = 15.6
Our calculation then becomes: 10 + 5.4 >= 16 which is false
To fix this we can do Math.ceil
on the pageYOffset
value.
Hope that helps.
The accepted answer did not work for me. This did:
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
// you're at the bottom of the page
console.log("Bottom of page");
}
};
If you're looking to support older browsers (IE9) use the alias window.pageYOffset
which has slightly better support.
$(document).ready(function(){
$('.NameOfYourDiv').on('scroll',chk_scroll);
});
function chk_scroll(e)
{
var elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight())
{
alert("scrolled to the bottom");
}
}
if you love jquery
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
// doSomethingHere();
}
});
I had to come up with a way (in Java) to systematically scroll down looking for a component for which I didn't know the correct XPath (long story, so just play along). As I just stated, I needed to scroll down while looking for a component and stop either when the component was found or the bottom of the page was reached.
The following code snippet controls the scrolling down to the bottom of the page:
JavascriptExecutor js = (JavascriptExecutor) driver;
boolean found = false;
long currOffset = 0;
long oldOffset = 0;
do
{
oldOffset = currOffset;
// LOOP to seek the component using several xpath regexes removed
js.executeScript("window.scrollBy(0, 100)");
currOffset = (Long)js.executeScript("var offset = window.window.pageYOffset; return offset;");
} while (!found && (currOffset != oldOffset));
By the way, the window is maximized before this code snippet is executed.