2

Using Jetpack Infinite Scroll & Isotope (Masonry).

I am facing an issue where after every new ajaxed set of posts, I need to destroy and then build isotope layout. If I don't go with this approach the new set of posts loaded by infinite scroll each time are not treated by isotope layout as its own and they miss on isotope styling. So, I need to rebuild isotope every time on post-load trigger of infinite scroll.

This approach actually leaves the user with a flick effect and scrolls to the beginning of isotope layout.

//In functions.php
function vg_infinite_scroll_init() {
    add_theme_support( 'infinite-scroll', array(
        'container'         => 'row-wrap',
        'type'               => 'scroll',
        'render'            => 'loop_p_arch_infinite_scroll_render',
        'footer'            => false,
        'footer_widgets'     => false,
        'wrapper'            => false,
        'posts_per_page'    => 9,
    ) );
}

add_action( 'after_setup_theme', 'vg_infinite_scroll_init' );

function loop_p_arch_infinite_scroll_render() {

    while( have_posts() ) {
        the_post();
            get_template_part( 'content', 'product' );
    }

}

function vg_get_prod_arch_posts( $post_type = 'post' ) {

    $prodarch_posts = get_posts( array(
        'numberposts'     => 9,
        'paged'         => get_query_var( 'paged' ),        
        'post_type'       => $post_type
    ) );

    return $prodarch_posts;

}

// In archive-product.php
<!-- Isotope Grid -->
<section id="product_list">
    <div class="container">
        <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="grid" id="row-wrap">
                        <div class="grid-sizer"></div>
                        <?php
                        $products = vg_get_prod_arch_posts( 'product' );

                        if ( ! empty( $products ) ) {
                            foreach ( $products as $product ) { 

                            setup_postdata( $GLOBALS['post'] = $product );
                            get_template_part( 'content', 'product' );

                            }
                            wp_reset_postdata();
                        }
                        ?>
                </div>
            </div>
        </div>
    </div>
</section>

//In content-product.php
global $post;
?>
<div class="grid-item post product">
    <div class="item_content">
        <a href="#">
            <div class="item_name"> 
                <h4><?php the_title(); ?> </h4> 
            </div>
            <?php echo get_the_post_thumbnail( $post->ID, 'large', array( 'class' => 'image_width_set' ) ); ?>
        </a>
    </div>
</div>

//In JS file

jQuery(document).on("post-load", function(e) {
    jQuery('.grid').isotope('destroy');
    jQuery('.grid').isotope({
        itemSelector: '.grid-item',
        percentPosition: true,
        masonry: {
            columnWidth: '.grid-sizer',
            gutter: 5
        }
    });
});

jQuery(window).load(function(){
    jQuery('.grid').imagesLoaded(function() {
        jQuery('.grid').isotope({
            itemSelector: '.grid-item',
            percentPosition: true,
            masonry: {
                columnWidth: '.grid-sizer',
                gutter: 5
            }
        });
    })
})
1

Usually isotope allows appending new items and then just re-layout the masonry again:

Somewhere in your JS file you should put the elements you want to append into a variable, e.g. new_elements

jQuery('.grid').append(new_elements)
    .isotope('appended', new_elements)
    .imagesLoaded( function() {
        jQuery('.grid').istotope('layout');
    });

Source: http://isotope.metafizzy.co/methods.html

The solution

Thanks to @vajrasar for the final touches.

When you echo the Grid-Page Loop, add the following:

function loop_p_arch_infinite_scroll_render() {
    $paged = get_query_var( 'paged', 1 );
    ?>
    <div id="page-<?=$paged?>">
        <?php while( have_posts() ) {
            the_post();
            get_template_part( 'content', 'product' );
        }
        ?>
    </div>
    <script id="script-page-<?=$paged?>">
        jQuery('document').ready(function($) {
            var new_elements = $('#page-<?=$paged?>').children('.grid-item');
            $('.grid')
                .append(new_elements)
                .isotope('appended', new_elements)
                .imagesLoaded( function() {
                    $('.grid').isotope('layout');
                });
            $('#page-<?=$paged?>, #script-page-<?=$paged?>').remove();
        });
    </script>
    <?php
}
  • I know, but the problem is that there is no way with Infinite Scroll where I can fetch the next set of posts in an array or something. – vajrasar Mar 12 '16 at 12:32
  • 1
    usually there should be hooks u can use.. if u don't find any go through the code that handles the isotope implementation and post the relevant lines. edit found it... will edit when i got a bigger screen. ;) – iantsch Mar 12 '16 at 13:46
  • vajrasar, have you tried the improvements? – iantsch Mar 14 '16 at 2:51
  • thanks for the code. I implemented it as is but it gave blank screen and also there was a typo in isotope spelling. But logic was bang on. Hence, I modified the code a bit and finally got it working. gist.github.com/vajrasar/359fbb4a89e68f1bd1d5 Please update your code to reflect this. I accepted it as THE answer. Thanks a lot for helping! :) Cheers. – vajrasar Mar 14 '16 at 11:48
  • 1
    @vajrasar bugs should be fixed. :) – iantsch Mar 14 '16 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.