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.
