Search code examples
jqueryajaxappenditerationmasonry

Target only the last appended div with Shuffle.js


I have a "load more" button that, when clicked, appends a new container to my search page with results. Each container gets a class that iterates (ex: .results-1 .results-2 .results-3) depending on how many items there are to load.

The problem is that when I click "load more," all results flash onto the screen, not just the newly appended items. This is because my code is detecting all items in the masonry grid, not just the appended ones.

This line is the problem, I think:

$('.gallery-photo [class of only most recent append goes here?]').each(function() {

How can I target the most recently appended items, when each new container gets a class that iterates?

Any ideas are greatly appreciated! Here's an example fiddle without the php.

$(function() {
  $(".gallery-photo").slice(0, 4).show();
  $("#loadMore").on('click', function(e) {
    e.preventDefault();
    $(".gallery-photo:hidden").slice(0, 4).fadeIn();
    $('.gallery-photo').each(function() {
      var $newRow = $(this);
      $('.masonry-gallery').append($newRow);
      $('.masonry-gallery').shuffle('appended', $newRow);
    });
  });
});

$(document).ready(function() {
  var $grid = $('.masonry-gallery');
  $grid.shuffle({
    itemSelector: '.gallery-photo' // the selector for the items in the grid
  });
});

P.S. This masonry grid utilizes shufflejs. A similar conversation here uses the same code for appending the new items into the grid.


Solution

  • As you pointed out, the problem is that you appending all of the elements rather than just the elements that are faded in.

    To resolve that, you can chain the .each() method after the .fadeIn() method in order to iterate over all of the newly displayed elements and trigger a shuffle update:

    Updated Example

    $("#loadMore").on('click', function(e) {
      e.preventDefault();
    
      $(".gallery-photo:hidden")
        .slice(0, 4)
        .fadeIn()
        .each(function() {
          $('.masonry-gallery').shuffle('appended', $(this));
        });
    });
    

    Based on your comment below, here is another alternative example where the elements are appended from another element (in this case there is a container element, #elements-to-append, which contains the elements that are appended).

    Updated Example

    var $gallary = $('.masonry-gallery');
    $gallary.find('.gallery-photo').show();
    
    var shuffle = new window.shuffle($gallary.get(0), {
      itemSelector: '.gallery-photo'
    });
    
    $("#loadMore").on('click', function(e) {
      e.preventDefault();
      var $elementsToAppend = $('#elements-to-append').children();
    
      $gallary.append($elementsToAppend);
      $elementsToAppend.fadeIn().each(function(_, element) {
        shuffle.add([element]);
      });
    });
    

    I replaced the jQuery script with the original shuffle script so that you could use the Shuffle .add() method in order to add the newly appended elements into the shuffle queue.