Infinite Scroll
- coding,Uncategorized
- Aug 5, 2012
- 11 Comments
Recently a client asked if he could have infinite scrolling on his website – and after having a good look around on a few websties, I found no decent tutorial. After working it out and having it work quite effectively (see www.matchlessphotography.com) I thought it perhaps a good idea to share with you how I went about it.
Keep in mind – the client was running a custom Wordpress theme that the company I am working for (BrownBox) made for him early this year.
When using WordPress
When using WordPress to do this, all we really want to do is run the get_posts() function and inject the new posts after our current ones. Pretty simple yeah?
Prerequisites
- Have a wordpress site (or a site running php pages) working that you’re able to test on.
- Have jQuery linked up
Step 1: Detecting the bottom of the page
Detecting the bottom of your page is actually pretty easy if you have jQuery installed – I used this neat little detector here:
$(window).scroll(function(){
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
alert("woah, rad - you're at the bottom dude");
};
});
Essentially about 10px before the bottom of the screen, you’ll get a polite little alert. Rad.
When you try this out – you’ll realise that it will alert you about 3 times when you get to the bottom of the page, this is because its checking for any value < 10px from the bottom. So when you are at 10px, you get an alert – when you are at 9px, you get an alert… etc.
This needs to be fixed as we don’t want to run our auto loader 3 times when they hit the bottom… so we need to wrap our rad little function in a timing checker:
var timing = 'good';
$(window).scroll(function(){
if(timing == 'good'){
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
timing = 'bad';
alert("woah, rad - you're at the bottom dude");
// insert the get posts function here
timing = 'good';
};
};
});
Ok Great – one more thing I want to give it, that is an offset – we don’t want to be loading the same posts each time our auto loader runs right? So if I’m going to load 20 posts at a time, the offset needs to increase by 20 each time also:
var offset = 0;
var timing = 'good';
$(window).scroll(function(){
if(timing == 'good'){
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
timing = 'bad';
offset = offset + 20;
// insert the get posts function here
timing = 'good';
};
};
});
Great – no we got the main part of of jQuery detector working.
Step 2: Tell the website to get more posts
There are two main stages here in this part, firstly is using jQuery to load a php page behind the scenes and then insert the result into the page.
This is actually dead easy and you do it with one line of code, with the jQuery load(); function.
$(".stall").last().append().load('http://matchlessphotography.com/more/?offset=' + offset,function(event){
timing = 'good';
event.preventDefault();
return false;
});
Essentially I created a page called More in the Wordpress backend that gets 20 posts, and uses an offset given to it in the url.
Check it out here: http://matchlessphotography.com/more/
Now also why not try changing the offset by using the variable on the end: http://matchlessphotography.com/more/?offset=20
Cool hey – as you can see also I am appending it into an existing div. This div I called “stall”… so you’d end up calling this whatever you want your content to appear in.
Ok so now we need to add all our javascript together and we end up with this: I put it in my header.php file before the closing head tag.
var offset = 0;
var timing = 'good';
$(window).scroll(function(){
if(timing == 'good'){
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
timing = 'bad';
offset = offset + 20;
$(".stall").last().append().load('http://matchlessphotography.com/more/?offset=' + offset,function(event){
timing = 'good';
event.preventDefault();
return false;
});
});
};
});
<?php
/*
template name: more
*/
?>
wp_head();
?>
<?php
$offset = mysql_escape_string($_REQUEST['offset']);
global $post;
$args = array('numberposts' => 20, 'meta_key=visible&meta_value=yes', 'offset' => $offset);
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<a class="photohovera" href="<?php the_permalink(); ?>">
<?php $url = wp_get_attachment_url( get_post_thumbnail_id($post->ID) ); ?>
<img src="<?php bloginfo('template_directory'); ?>/timthumb.php?src=<? echo $url ?>&h=138&w=197" width="197" height="138" title="<?php the_title(); ?>" />
<span class="spanno">
<strong class="title_blog_mini_post">
<?php the_title(); ?>
</strong>
</span>
</a>
<?php endforeach; ?>
<div class="stall"><!-- this is where the next lot will be injected --></div>
Comments (11)
colin
August 7, 2012
Its awesome and works fantastically. Your that MAN!!! Thanks for all your hard work.
benjaminpott
August 7, 2012
No worries Colin – Glad you liked it!
Kurazy
September 8, 2012
Cool post. But typo line 14 of last javascript code sample
Thanks
benjaminpott
September 8, 2012
Ok I’ve looked over and over and can’t see it – mind fixing it for me or sending me the mistakes?
Brandon
October 19, 2012
Looks to me like “});” should just be “}” closing the if statement on line 6.
benjaminpott
December 4, 2012
Thanks Mate! All fixed up now
RB
November 28, 2012
How would you do this with a straight PHP site, not wordpress, just php pages?
benjaminpott
November 29, 2012
Essentially the same more or less – the only difference would be on the more.php page, where instead of generating WordPress posts, you would generate more content… Is there a specific thing I can help you out with? I realise my answer was vague.
Aaron
December 4, 2012
Brandon is right. There’s a syntax error in the Javascript section. }); should be just }
benjaminpott
December 4, 2012
should be all fixed now
Aaron
December 4, 2012
Great! Thanks for the article. Glad I found this instead of installing another jQuery plugin. Didn’t even think it would be this easy.