Isotope with Infinite Scroll

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 Answer
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
}

Leave a Comment