Masonary image not positioning correctly on ajax call



I am using https://masonry.desandro.com/ v4.2.2 and the minimal code looks like:

<div class="fk-grid-container" id="ajax-concepts">
<?php
//This is just the wordpress loop and currently its looping and showing 3 items
//LOOP START
while ( $the_query->have_posts() ) :
    $the_query->the_post();
    $thumbnail_url = get_the_post_thumbnail_url('','full');
?>
    <div class="fk-grid-item">
        <a href="<?php echo $thumbnail_url; ?>" class="gallery-link">
            <div
                    class="boxes"
                    data-aos="fade-down"
                    data-aos-duration="2000"
            >
                <div class="images-box">
                    <img
                            src="<?php echo $thumbnail_url; ?>"
                            class="img-fluid"
                            alt="<?php the_title(); ?>"
                    />
                </div>
            </div>
        </a>
    </div>
<?php
//LOOP END
endwhile;
wp_reset_postdata();
?>
</div>

And, I have initalized it as :

jQuery(".fk-grid-container").imagesLoaded(function () {
    jQuery(".fk-grid-container").masonry({
        itemSelector: ".fk-grid-item",
        gutter: 30,
    });
    AOS.refresh();
});

Upto this point its fine, now on click load more, I am making an ajax call and on success it is returning html as:

<div class="fk-grid-item">
   <a href="http://famous.test/wp-content/uploads/2021/08/02.png" class="gallery-link">
      <div class="boxes" data-aos="fade-down" data-aos-duration="2000">
         <div class="images-box"><img src="http://famous.test/wp-content/uploads/2021/08/02.png"  class="img-fluid"  alt="Image 3" /></div>
      </div>
   </a>
</div>
<div class="fk-grid-item">
   <a href="http://famous.test/wp-content/uploads/2021/08/05.png" class="gallery-link">
      <div class="boxes" data-aos="fade-down" data-aos-duration="2000">
         <div class="images-box"><img src="http://famous.test/wp-content/uploads/2021/08/05.png"  class="img-fluid"  alt="Image 2" /></div>
      </div>
   </a>
</div>
<div class="fk-grid-item">
   <a href="http://famous.test/wp-content/uploads/2021/08/06.png" class="gallery-link">
      <div class="boxes" data-aos="fade-down" data-aos-duration="2000">
         <div class="images-box"><img src="http://famous.test/wp-content/uploads/2021/08/06.png"  class="img-fluid"  alt="Image 1" /></div>
      </div>
   </a>
</div>

and my ajax success:

success: function(data){
    var $data = jQuery(data);
    if($data.length){
        jQuery(".fk-grid-container").append(data).masonry( 'reloadItems' );
        AOS.refresh();
    }
},

But, with this code the image are not aligned to correct position and is displayed as:

Wrong stacking image

This is what it looked initially:

Initially

What it should look like:

enter image description here

Update:

I have tried with:

var $grid = $('.fk-grid-container');
$grid.masonry()
    .append( $data )
    .masonry( 'appended', $data )
    .layout();
AOS.refresh();

I have tried with above code, it is adding the new content but it is not increasing the height of current container and instead overlapping over next container. With this the load data button is covered by the data so I can’t make another request.

Answer

On load more, it looks like you are not making use of imagesLoaded correctly.

Let’s take a look at your initialization code:

jQuery(".fk-grid-container").imagesLoaded(function () {
    jQuery(".fk-grid-container").masonry({
        itemSelector: ".fk-grid-item",
        gutter: 30,
    });
    AOS.refresh();
});

above one is correct

But, on success (according to your last update) you are doing as:

var $grid = $('.fk-grid-container');
$grid.masonry()
    .append( $data )
    .masonry( 'appended', $data )
    .layout();
AOS.refresh();

Actually, the above code is somehow correct you just need to update the layout once all the images are loaded and you have to update that layout part to masonry (because it looks like you are using jquery). Just like here, mentioned in the first block https://masonry.desandro.com/methods.html

So, the final code should look like this:

var $grid = $('.fk-grid-container');
//appending the data on the grid 
$grid.masonry()
    .append( $data )
    .masonry( 'appended', $data );


$grid.imagesLoaded(function(){
//once images are fully loaded, you update the layout
    $grid.masonry();
    AOS.refresh();
});

Hope, it helps



Source: stackoverflow