JetPack Infinite Scroll + Masonry

jetpack-banner

I added support for Jetpack Infinite Scroll on a theme of mine that uses Masonry recently.

Since I couldn’t find any good code snippets or recommendations for how the callback should work I wanted to share a couple methods I tried. If anyone has improvements or recommendations, please let me know.

All of these examples use the “post-load” javascript event that Jetpack triggers. You can read about that on the Jetpack Infinite Scroll documentation page.

The Simplest

Trigger a re-layout after the new elements load in. The only issue with this that I’ve seen is a flash of un-organized posts layered on top of each other before the re-layout actually happens. (Solution found in this WordPress.org thread).

jQuery( document ).ready( function( $ ) {
	setInterval( function() {
     	$( '#content' ).masonry( 'reload' );
     }, 300 );
});

More Convoluted

Desandro recommends using the appended method in his docs. This is a bit more complicated to implement because you need to figure out which are the new elements.

Jetpack doesn’t pass the new elements in the “post-load” event, but does append a new div “.infinite-wrap” with a unique id “#infinite-view-1″. So, if you keep track of how many times the event has fired, you’ll be able find the div that contains the new elements.

Here was my attempt at that (works, but the new element layout never seems to be 100% consistent):

jQuery( document ).ready( function( $ ) {
     infinite_count = 0;
     // Triggers re-layout on infinite scroll
     $( document.body ).on( 'post-load', function () {
	infinite_count = infinite_count + 1;
	var $container = $('#content');
	var $selector = $('#infinite-view-' + infinite_count);
	var $elements = $selector.find('.hentry');
	$elements.hide();
	$container.masonry( 'appended', $elements, true );
	$elements.fadeIn();
     });
});

Final

This final method I went with is a bit of the mix between the two. It uses the “reload” method which seems to be more consistent, but also keeps track of which are the new elements and fades them in as they load. This seemed to create a smoother visual effect than simply popping them into place.

jQuery( document ).ready( function( $ ) {
     infinite_count = 0;
     // Triggers re-layout on infinite scroll
     $( document.body ).on( 'post-load', function () {
	infinite_count = infinite_count + 1;
	var $container = $('#content');
	var $selector = $('#infinite-view-' + infinite_count);
	var $elements = $selector.find('.hentry');
	$elements.hide();
	$container.masonry( 'reload' );
	$elements.fadeIn();
     });
});

Feedback

If you have any suggestions or feedback as to improve this code, please let me know.

Other Resources

About Devin

I'm a WordPress developer based in Austin, Texas. Follow my projects on GitHub, or more general WordPress ramblings as @devinsays on twitter.

25 Responses

      1. Primo

        btw, there are some inconstistence
        sometimes it mix the pages, instead to make a infinite one…
        didn’t get why.
        solution? :/

  1. Peter

    This is beautiful. Thanks for sharing it. I am curious if you would know of any reason why this will not work on search.php? The code is the same from index.php except for the added search box. The search and masonry work, but no infinite scroll. I am using “click” not “scroll” and the site is protected right now so I am unable to share. I am not in dire need of an answer, so if there isn’t one, that’s fine. Thanks for any help though!

    Peter

  2. Ahhh yes, someone who has documented how do this!

    I am wanting to add it to the Motion I theme I use, as I have given up hope that the developers themselves will do it (they haven’t updated the theme in over two years).

    Will give this an attempt soon!

  3. Hi Devin! I’m using the visual theme along with jetpack for infinite scroll for a industrial design portfolio of mine, http://www.design-works.gr. It works just fine.

    The problem starts when i activate permalinks (postname) from the wp dashboard. Infinite scroll works ok in front page but not in the category page. Scrolling stops, without loading any more posts below. Any ideas why this is happening?

    Thank you in advance.

  4. jose

    Great Devin !!
    I have a weird behavior with paging / scrolling, once loaded the posts no math for the paging order, on top url changes to the last one, etc. Do you have the same issue?
    Figured out how to have the same effect as maonry isAnimatedFromBottom?

    Many thanks.

      1. Eder Oliveira

        Nice tutorial! I have disabled the URL PushState with:

        'wrapper' => false,
        'render' => false 
        

        works fine :)

      2. Thanks Devin!

        Just wanted to chime in and say that you can unhook the push state functionality by calling the following after infinity.js is loaded:

        $(document.ready( function() {
        $(window).unbind('scroll');
        });

  5. I recently used this technique on my website but I have a problem: My post preview have a rel property to view content in a modal. The first post that are not loaded with Masonry works well, but the rest are not within the modal.

    Any idea how I could fix it?

  6. Thanks for the tutorial.

    So I put
    function inf_masonry(){
    wp_enqueue_script('inf-masonry', get_template_directory_uri() . 'http://news.enigma-tech.co.uk/wp-content/themes/ETN/inf-masonry.js', array( 'jquery' ));
    }

    add_action('wp_enqueue_scripts', 'inf_masonry');

    in my functions.php

    But how and where should I be calling inf_masonry() ?

    I’m currently using the HTML initialisation of Masonry. Will that be okay, with a jQuery reload, or should I init in jQuery too?

  7. Hi,

    I’m facing the same issue.

    I added above code into my theme’s js file and it didn’t work.

    Also i use caching , does that cause any issue?

    You can check it here.
    http://www.itdealraja.com/

    MY theme js file is

    http://www.itdealraja.com/wp-content/themes/birdflat/birdflat/js/birdflat.js

    And My theme support is

    `function test_scrol() {
    add_theme_support( ‘infinite-scroll’, array(
    ‘container’ => ‘content’,
    ‘type’ => ‘click’,
    ‘wrapper’ => ‘masonry-wrapper’,
    ‘footer’ => ‘page’,
    ‘posts_per_page’ => ‘8’
    ) );
    }
    add_action( ‘after_setup_theme’, ‘test_scrol’ );
    `

    Any help appreciated.

  8. Hi… I’m using your code but it does not seem to work… I don’t know what to do… I’m trying to implement jetpack + masonry on my site but it’s not working.

    Thanks in advance.
    Regards.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>