19

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
                }
            })
        }
})
Cristian
  • 6,765
  • 7
  • 43
  • 64
  • Is the goal to save bandwidth for mobile devices? – makerofthings7 Nov 22 '11 at 00:32
  • no, at the moment I have one javascript which detects the user agent of a mobile device, and executes a certain code, which atm isn't 100% and only works on iphone, else it executes the normal code which works on all desktop browsers – Cristian Nov 22 '11 at 10:07

10 Answers10

17

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

compid
  • 1,313
  • 9
  • 15
Nick Malcolm
  • 726
  • 4
  • 18
  • hey all, what nick said is what Im also doing in conjunction with the plugins I mention below – tim peterson Apr 17 '12 at 11:39
  • Thanks, I was trying to find a solution for this for a while. This worked. – Felipe Brahm May 15 '12 at 04:05
  • 3
    FYI: If the document is scaled down (the user zooms out), jQuery actually returns the wrong height for $(window).height(), so I have had to use window.innerHeight if it exists, or else fall back on $(window).height() – mltsy Feb 19 '13 at 18:24
3

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.

Enigma Plus
  • 1,519
  • 22
  • 33
  • dude seriously, you are my star...rockstar... a celebrity for me right now. You saved me...Thanks a (millions)^millions. – Bhavik Shah Aug 23 '13 at 06:43
3

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
    });
  });
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Finbey
  • 31
  • 1
  • You need to replace var pTop with this: var pTop = $(window).scrollTop() < this.previous && $(window).scrollTop() <= 0; – Code Uniquely Jan 10 '14 at 06:30
2

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?

Community
  • 1
  • 1
Tonatiuh
  • 2,205
  • 1
  • 21
  • 22
1

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
  }
});
bloke_zero
  • 508
  • 7
  • 12
1

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)
    );
}
Strelok
  • 50,229
  • 9
  • 102
  • 115
  • 1
    @qwertymk I'm pretty sure this is a bullet proof way to *get document height on all browsers*, including mobile browsers. I didn't specify that this is a bullet proof way to get maximums from a bunch of numbers :) Check this jsFiddle in anything you have with a web browser and you will get the correct number: http://jsfiddle.net/z5BM8/ – Strelok Nov 22 '11 at 00:31
0

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

tim peterson
  • 23,653
  • 59
  • 177
  • 299
0

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.

Jamon Holmgren
  • 23,738
  • 6
  • 59
  • 75
0

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

Thinking
  • 747
  • 5
  • 11
0

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

Keith.Abramo
  • 6,952
  • 2
  • 32
  • 46
  • I will try adding the meta tags now. I have already fixed the issue of there not being enough content by first checking whether the $(document).height() == $(window).height(), and if so loading content 3 at a time until they are not equal – Cristian Nov 22 '11 at 10:08