JetPack Infinite Scroll + Masonry

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 am a developer based in Austin, Texas. I run a little theme shop called DevPress and help manage a WooCommerce shop with Universal Yums. Find me on twitter @devinsays.

31 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. Yen

    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.

  9. Ulrich

    The code was not working fully for with the latest version of Masonry (v3.x.x). This is what I ended up using.


    if (typeof jQuery != 'undefined') {
    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 = $('#infinite-view-' + infinite_count);
    // initialize
    $container.imagesLoaded( function() {
    $container.masonry({
    columnWidth: 400,
    gutter: 32,
    itemSelector: '.hentry'
    });
    });
    });
    });
    }

  10. jaffa

    Hello,

    I’m struggling to get Jetpack Infinite Scroll and masonry to work in WordPress. I have tried so many different tutorials but cannot seem to get it working. I don’t understand why the posts are loaded in batches of 7 with each infinite-view-# div, is this how it’s supposed to work? I have not declared the number 7 anywhere.

    The site is being developed on localhost therefore unable to share link. The theme is based on Underscores theme.

    I have used the code provided by Ulrich. How do I incorporate imagesLoaded into this as well?

    Any assistance would be greatly appreciated.

    Thanks

    J

  11. Greg

    I’m having a hard time re-positioning the featured image. If I set the grid_image_size to 0, I can use a hook at add a featured image where I want it- but then it’s missing from all infinite scroll loaded posts…

    Anyone have any ideas how to gain control over the placement of the images and infinite scrolling?

    1. Greg

      I “sorta” got what I wanted working, but it seems like more work than is necessary- I must be missing something.

      The only way I found to combine grid layout, infinite scrolling and control over the layout was to define a custom grid loop.

      Heading into genesis loops.php I copied out the grid loop function. Modified the function too suit, placed it in it’s own PHP file and then used include_once on that file.

      Once that file is loaded and working we have access to the new loop function. From there, you set the “render” args on the add_theme_support declaration.

      So for me this was:

      ‘render’ => ‘custom_grid_loop’,

      Once all of that is in place, I can call custom_grid_loop on my index.php page to get the loop started. Then infinite scrolling will use this function to add additional posts passed my posts_per_page value.

      Hope that helps someone else… and…. if there’s a more simple way to achieve the above please let me know!

Leave a Reply