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?
-
2possible 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
-
1Possible 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 Answers
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.

- 310
- 3
- 16
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>

- 3,007
- 1
- 17
- 22
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>

- 153
- 1
- 11