19

Head's up!

There's a pending feature-request issue on Isotope's GitHub repo that you should add a "" reaction to if you're interested in seeing official docs and demos for this (how to combine Isotope, Infinite Scroll, filtering, and sorting). It was opened by Isotope's creator to gauge interest. If interested, please upvote!

TL;DR: To help get official docs and demos for this, go here and add a "" reaction.


Trying to piece together a filterable layout using the Isotope JS plugin and Paul Irish's (sadly unmaintained) Infinite Scroll plugin.

Filtering is somewhat working. Initially it filter the page 1 content. For it to filter items not on page 1 I need to scroll down (I suppose this is bringing the elements in the browser's memory, thus making it available to the filtering script?)

via a set of select boxes for the initial page content (ie: the content on page 1).

Question 1: How to get the filter to work for all page items? ie: How to reference all elements in the filter script, even those not yet brought onto the page via infinite scroll?

Question 2: Once I have scrolled down and all the elements are filterable, the window does not resize on filtering. so when there's only one or two elements show via the filter, it's still possible to scroll way down the page (even though no elements are shown). Upon inspection of these elemnts, I see that they're still in the DOM.

Filtering Script

function filterTags(){
  isotopeInit();

  var $checkboxes = $('#tag-wrap input')

  $checkboxes.change(function(){
    var arr = [];
    $checkboxes.filter(':checked').each(function(){
      var $dataToFilter = $(this).attr('data-filter');
      arr.push( $dataToFilter );
    });
    arr = arr.join(', ');
    $container.isotope({ filter: arr });
  });
};

Isotope Init

function isotopeInit(){
  var $container = $('.post-excerpts').imagesLoaded( function() {
    $container.isotope({
      itemSelector: '.post-excerpt-block-wrap',
      layoutMode: 'masonry',
      animationEngine: "best-available",
      masonry: {
        columnWidth: '.post-excerpt-block-wrap' 
      },
      transitionDuration: '2.0',
       hiddenStyle: {
        opacity: 0
      },
      visibleStyle: {
        opacity: 1,
        transform: 'scale(1)'
      }
    });
  });
};

Infinite Scroll Init

$container.infinitescroll({
  loading: {
    finished: undefined,
    finishedMsg: "<em>No more posts to load.</em>",
    img: "http://www.infinite-scroll.com/loading.gif",
    msg: null,
    msgText: "<em>Loading the next set of posts...</em>",
    selector: '.infinite-loader',
    speed: 'fast',
    start: undefined
  },
  binder: $(window),
  //pixelsFromNavToBottom: Math.round($(window).height() * 0.9),
  //bufferPx: Math.round($(window).height() * 0.9),
  nextSelector: "a.older-posts",
  navSelector: "nav.pagination",
  contentSelector: ".content",
  itemSelector: ".post-excerpt-block-wrap",
  maxPage: {{pagination.pages}},
  appendCallback: true
},
  // Callback for initializing scripts to added post excerpts
  function(newElements) {
    var $newElems = $( newElements );
    loadImages();
    checkForFeatured();
    makeFontResponsive();
    addReadMoreLinks();
    fitVidInit();
    $newElems.imagesLoaded(function(){
      $container.isotope( 'appended', $newElems );
    });
  }
);

Any ideas, suggestions, or other insight incredibly welcomed. Many thanks in advance.

Update:

Regarding Questions 2: Seems the problem is related to how Isotope is being told to filter the items. Specifically, this code from the isotope init function:

transitionDuration: '2.0',
hiddenStyle: {
  opacity: 0
},
visibleStyle: {
  opacity: 1,
  transform: 'scale(1)'
}

I've tried changing it to the following, though this removes the completely from the DOM (fixing the spacing issue) and they're not returned into the DOM upon "unfiltering" them. So it's not a solution:

hiddenStyle: {
  display: 'none'
},
visibleStyle: {
  display: 'visible',
  transform: 'scale(1)'
}

I've also tried simply removing these config lines all together, which seems like the obvious "clean" solution, but this too still leaves lots of white space on the page upon filtering. Not sure whether the problem here is with my Isotope or Infinite Scroll implementation.

Isaac Gregson
  • 1,325
  • 1
  • 14
  • 27

1 Answers1

0

For question 2, one thing you could do is applying the display:none style to all hidden elements (and remove from all the visible ones) after isotope filtering.

I think you should be able to use the "on layoutComplete" event listener of isotope to apply it at the right time, like this:

$container.isotope( 'on', 'layoutComplete',
      function( isoInstance, laidOutItems ) {

          $('.my-elements-class.hiddenStyle').addClass('reallyHiddenStyle');
          $('.my-elements-class.visibleStyle').removeClass('reallyHiddenStyle');
      }
);

Where, of course, the elements you want to filter are of css class my-elements-class, you applied isotope filtering to $container and you define

reallyHiddenStyle: {
  display: 'none'
}

in your CSS.

For question 1, perhaps you need to use a similar strategy with infinitescrolling callback, adding new elements to the filter once they appear because of scrolling. You already have the callback passed as last parameter of the infinitescroll method, so at a quick look it seems that something like this might work:

$container.isotope('destroy');
$.each(newElements, function (i, el){/** add new elements to arr */});
$container.isotope({ filter: arr });

Do you have a working example you can share? So that I can check it out, if you'd like me to.

mlr
  • 806
  • 6
  • 13