Cristian
Cristian

Reputation: 7185

JQuery Detect Scroll at Bottom

I wish to achieve content load when the user scrolls to the bottom of the page.

I am having a problem. It works fine on desktop browsers but not on mobile. I have implemented a dirty fix to make it work on the iPhone, but is not optimal as it won't work on other sized mobile devices.

My website is www.cristianrgreco.com, scroll down to see the effect in action

The problem is adding the scroll and the height do not equal the height on mobile devices, whereas they do on desktop browsers.

Is there a way to detect for mobile browsers?

Thanks in advance.

Below is the code currently being used:

$(document).ready(function () {
        $(".main").hide().filter(":lt(3)").show();
        if ($(document).height() == $(window).height()) {
            // Populate screen with content
        }
        else if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i)) {
            window.onscroll = function () {
                if ($(document).height() - $(window).scrollTop() <= 1278) {
                    // At the moment only works on iPhone
                }
            }
        }
        else {
            $(window).scroll(function () {
                if ($(window).scrollTop() + $(window).height() >= $(document).height()) {                     
                    // Works perfect for desktop browsers
                }
            })
        }
})

Upvotes: 19

Views: 28359

Answers (10)

Thinking
Thinking

Reputation: 737

Though the question was asked 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

Upvotes: 0

bloke_zero
bloke_zero

Reputation: 508

Using jquery and Strelok's getDocumentHeight() below (cheers!) I found the following worked pretty well. Testing for equality didn't work for me as the iPhone only registered a scroll value at the end of the slide which was actually greater than the document height:

$(window).scroll(function () {
  var docHeight = getDocumentHeight();         
  if ($(window).scrollTop() + $(window).height() >= docHeight) {
    // Do stuff
  }
});

Upvotes: 1

Tonatiuh
Tonatiuh

Reputation: 2525

This is what worked for me:

(window.innerHeight + window.scrollY) == $(document).height()

Found here: Javascript: How to detect if browser window is scrolled to bottom?

Upvotes: 2

Nick Malcolm
Nick Malcolm

Reputation: 726

For anyone who looks here later, I solved this by adding height=device-height to the meta viewport tag:

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">

You can then carry on using $(document).scroll(function(){});

This worked with iOS 5

Upvotes: 17

Finbey
Finbey

Reputation: 31

An improved jQuery version of the code

var scrollRefresh = {
    pastTop: false,
    pastBottom: false,
    previous: 0,
    bottom: function(callback) {
      var pBottom = $(window).height() + $(window).scrollTop() >= $(document).height();
      if(!this.pastBottom && pBottom) {
        callback($(window).height() + $(window).scrollTop());
        this.pastBottom = true;
      } else {
        if(!pBottom) this.pastBottom = false;
      }
      this.previous = $(window).scrollTop();
    },
    top: function(callback) {
      var pTop = $(window).scrollTop() < this.scrollPrevious && $(window).scrollTop <= 0;
      if(!this.pastTop && pTop) {
        callback($(window).scrollTop());
        this.pastTop = true;
      } else {
        if(!pTop) this.pastTop = false;
      }
      this.previous = $(window).scrollTop();
    }
  }

  $(window).scroll(function() {
    scrollRefresh.top(function(pos) {
      console.log("Loading top. " + pos);
      alert("scrolled to top"); //You should delete this line
    });
    scrollRefresh.bottom(function(pos) {
      console.log("Loading bottom. " + pos);
      alert("scrolled to bottom"); //You should delete this line
    });
  });

Upvotes: 3

Jamon Holmgren
Jamon Holmgren

Reputation: 24420

Here is an aggregate of the other answers which works very well for me. It could be written as a jQuery plugin sometime.

// Handles scrolling past the window up or down to refresh or load more data.
var scrolledPastTop = false;
var scrolledPastBottom = false;
var scrollPrevious = 0;

function getDocumentHeight() {
  return Math.max(
      Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
      Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
      Math.max(document.body.clientHeight, document.documentElement.clientHeight)
  );
}

function bottomScrollRefresh(callback) {
  var pastBottom = $window.height() + $window.scrollTop() > getDocumentHeight();
  if(!scrolledPastBottom && pastBottom) {
    callback($window.height() + $window.scrollTop());
    scrolledPastBottom = true;
  } else {
    if(!pastBottom) scrolledPastBottom = false;
  }
  scrollPrevious = $window.scrollTop();
}

function topScrollRefresh(callback) {
  var pastTop = $window.scrollTop() < scrollPrevious && $window.scrollTop() <= 0;
  if(!scrolledPastTop && pastTop) {
    callback($window.scrollTop());
    scrolledPastTop = true;
  } else {
    if(!pastTop) scrolledPastTop = false;
  }
  scrollPrevious = $window.scrollTop();
}

To use this in your code, add something like this:

window.onscroll = function() {
  topScrollRefresh(function(pos) {
      console.log("Loading top. " + pos);
  });
  bottomScrollRefresh(function(pos) {
    console.log("Loading bottom. " + pos);
  });
};

Works great for my PhoneGap/Cordova app.

Upvotes: 0

Enigma Plus
Enigma Plus

Reputation: 1548

If you can, you should really avoid trying to hit an exact number.

Using Stelok's function above, you can test like this:

if ($win.height() + $win.scrollTop() > (getDocumentHeight()-10)) {

It's a bit softer - the user may not have quite scrolled to the exact last pixel but thinks he/she is at the bottom.

Upvotes: 3

tim peterson
tim peterson

Reputation: 24315

you can also use an endless scroll plugin: https://github.com/fredwu/jquery-endless-scroll https://github.com/paulirish/infinite-scroll

i'm using the endless scroll and it works great on my laptop and iphone

Upvotes: 0

Keith.Abramo
Keith.Abramo

Reputation: 6965

Have you added the meta tag for iphones which sets the content size to the viewport of the phone?

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">

EDIT:

So I tried this on my phone (android, gingerbread) and the issue wasn't so much the code not working it was the content displayed does not force the page to scroll. As soon as I zoomed in and scrolled down more content dynamically loaded. You could try adding content until the content added is greater than $(window).height();

Upvotes: 0

Strelok
Strelok

Reputation: 51481

Bullet proof way to get document height on all browsers:

function getDocumentHeight() {
    return Math.max(
        Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
        Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
        Math.max(document.body.clientHeight, document.documentElement.clientHeight)
    );
}

Upvotes: 1

Related Questions