0

I've been asked to design a site that continuously expands as the user keeps scrolling. Im experienced in JavaScript but I've never came across anything that could manage this. Popular sites that use this technique are Twitter and Facebook. I know that I'm going to need AJAX to load more content but I'm unsure as to how the browser will know that the user is nearing the bottom of the page?

George
  • 36,413
  • 9
  • 66
  • 103
  • 2
    possible duplicate http://stackoverflow.com/questions/2837741/jquery-detecting-reaching-bottom-of-scroll-doesnt-work-only-detects-the-top – yogi Aug 21 '12 at 12:17
  • 1
    Possible duplicate and a quick Google gives you this: https://github.com/paulirish/infinite-scroll – jValdron Aug 21 '12 at 12:21
  • Google Reader does this. You can take a peek at their code. – eh9 Nov 14 '12 at 19:40

3 Answers3

5

You can do this using three JavaScript functions. The first is window.scrollY. This function will give you the height position on the webpage (i.e. if you are at the top it's 0, as you scroll down it increases).

The second is document.body.scrollHeight This gives you the total height of the window, including the scroll.

The final function is window.innerHeight. This gives you the height of the window that a user can see (the height of the visible part).

Using these three functions you can get the top and bottom positions of the browser window and the size of the entire page. From that you can figure out where the user is on the page and determine if the page should expand.

Patrick548
  • 310
  • 3
  • 16
1

Here's a self-contained example with fake AJAX calls, based on Patrick548's answer (which gets an upvote from me). Tested in Chrome.

This doesn't account for the user scrolling back to the top of the page, but support should be easy enough to add.

<!doctype html>
<html lang="en">
    <head>
        <title>Infinite Scroll Test</title>
        <style>
#articles {
    width: 200px;
}

.article {
    display: block;
    border: 1px solid #000;
    border-radius: 4px;
    background-color: #eee;
    margin-bottom: 1em;
}
        </style>

        <script>
var articleCounter = 0;

function fakeAjaxCall(cb) {
    var createNewArticle = function() {
            return {
                id: ++articleCounter
              , author: 'Foo Bar'
              , text: 'Lorem ipsum and all that jazz.'
            };
        }
      , articles = []
    ;

    for (var i=0; i<10; i++) {
        var fakeArticle = createNewArticle();
        articles.push(fakeArticle);
    }

    // call the fake success handler with the fake data
    if (cb && typeof(cb == 'function')) cb({ articles: articles });
}

function appendFakeData(data) {
    if (! data && data.articles) return;

    for (var i=0; i<data.articles.length; i++) {
        var article = data.articles[i]
        document.querySelector('#articles').innerHTML +=
            '<div class="article">[' + article.id + '] ' + article.author + ' sez:<br>' + article.text + '</div>';
   }

    var articleCount = document.querySelectorAll('.article').length;
    console.log('article count is now: ' + articleCount);

    if (articleCount > 50) removeFirstTenArticles();
}

function removeFirstTenArticles() {
    var articlesEl    = document.querySelector('#articles')
      , firstChild    = articlesEl.firstChild
      , articleStyle  = window.getComputedStyle(document.querySelector('.article'))
      , articleHeight = parseInt(articleStyle.height) + parseInt(articleStyle.marginBottom);
    ;

    // remove the first 10 articles in the container
    for (var i=0; i<10; i++) {
        articlesEl.removeChild(firstChild);
        firstChild = articlesEl.firstChild;
    }

    // scroll back to where the new articles were inserted
    document.body.scrollTop -= (10 * articleHeight);
}

window.addEventListener('load', function() {
    document.body.scrollTop = 0; // start at the top
    fakeAjaxCall(appendFakeData);
});

document.addEventListener('scroll', function(evt) {
    // if distance from bottom of page is zero, grab and append more articles
    if (document.body.scrollHeight - (window.innerHeight+window.scrollY) == 0) {
        console.log('getting more data...');
        fakeAjaxCall(appendFakeData);
    }
});
        </script>
    </head>

    <body>
        <section id="articles"></section>
    </body>
</html>
psema4
  • 3,007
  • 1
  • 17
  • 22
0

http://www.youtube.com/watch?v=eziREnZPml4

<script type="text/javascript">
function yHandler();
var wrap = document.getElementById('wrap');
    var contentHeight = wrap.offsetHeight;
var yOffset = window.pageYOffset; 
var y = yOffset + window.innerHeight;
if(y >= contentHeight){
    // Ajax call to get more dynamic data goes here
    wrap.innerHTML += '<div class="newData"></div>';
}
var status = document.getElementById('status');
status.innerHTML = contentHeight+" | "+y;
}

window.onscroll = yHandler;
</script>
JensenS
  • 153
  • 1
  • 11