Stories and Thoughts

but only the good things worth sharing...

August 5, 2012

Infinite Scroll

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

  1. Have a wordpress site (or a site running php pages) working that you’re able to test on.
  2. 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;
       });
     });
   };
 });
Ok one last thing now, and that is to make the php file itself. Dead easy, here’s mine. Note how I get the offset variable in the beginning lines from the url:
<?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>
Step 3: finished
Hope this all made sense – if not please leave a comment and I’ll work with you on it. Make sure you have a look at the full working version though here:
http://matchlessphotography.com/
Thanks again for reading.