Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isotope filtering + Lazy loading #58

Open
latinunit opened this issue Oct 1, 2012 · 12 comments
Open

Isotope filtering + Lazy loading #58

latinunit opened this issue Oct 1, 2012 · 12 comments

Comments

@latinunit
Copy link

I've spent considerable amount of time trying to get isotope and lazy loading working together.

The issue: lazy loading works if the user scrolls down, however if the user uses the filters, the items show up on top but the images will not load.

Here is someone with the same issue, but it seems he fixed it. I tried several things but still couldnt get it working.

Here is the dicussion #51

Thanks alot for your help

The code I am using is as follow.

jQuery(document).ready(function($) {
$('#big_container .media_block img').each(function(index) {
var item_height = $(this).attr("height");
$(this).parent().parent().css("height",item_height);
});
$('#big_container').isotope({
itemSelector : '.item',
layoutMode : 'masonry',
masonry: {
columnWidth: 5,
},
sortBy : 'date',
sortAscending : false,
getSortData : {
date : function ( $elem ) {
return $elem.find('.date').text(); // Date format should be [Y-m-d H:i]
},
views : function( $elem ) {
return parseInt( $elem.attr('data-views'), 10 );
},
//featured : function ( $elem ) {
// return $elem.attr('data-featured');
// },
rates : function( $elem ) {
return parseInt( $elem.attr('data-rates'), 10 );
},
comments : function( $elem ) {
return parseInt( $elem.attr('data-comments'), 10 );
}
}

});

$('#sort-by li a').click(function(){
    var $this = $(this);
    if ($(this).parent().hasClass('selected') ) {
      return false;
    }
    var $optionSet = $this.parents();
    $optionSet.find('.selected').removeClass('selected');
       $this.addClass('selected');
      var sortName = $(this).attr('href').slice(1);
      $('#big_container').isotope({ sortBy : sortName });
      return false;
});

});

@acarabott
Copy link

I spent a lot of time with this and finally found a solution!

According to the docs (http://www.appelsiini.net/projects/lazyload)

Order of images on page is same as order of images in HTML code. With some layouts assumption this might be wrong.

With isotope sorting/filtering, this assumption lets us down. Fortunately we can handle this by increasing our failure_limit.

Setting failure_limit to 10 causes plugin to stop searching for images to load after finding 10 images below the fold. If you have a funky layout set this number to something high.

We can be a bit more precise than "something high", we can store the jQuery object we call .lazyload() on and use its length (more precisely we use the length-1, ensuring it is at least 0 because of lazyload checks against the value; using ++counter).

if (++counter > settings.failure_limit) {
    return false;
}

We also need to ensure that the update method is called after we do our isotope sorting/filtering, so we trigger it using the onLayout callback

Solution:

var $imgs = ('img.lazy');
var $container = $('#container');
var $window = $(window);

$imgs.lazyload({
    failure_limit : Math.max($imgs.length-1, 0);
});

$('#sort-asc li a').click(function() {
    $container.isotope({
        layoutMode: 'straightDown',
        onLayout: function() {
            $window.trigger("scroll");
        }
    })
});

Working jsFiddle

http://jsfiddle.net/arthurc/ZnEhn/

@tuupola
Copy link
Owner

tuupola commented Dec 17, 2012

Awesome. Thanks!

@kenliu
Copy link

kenliu commented May 9, 2013

Another way to deal with this is to set the isotope items to trigger on a custom jQuery event in addition to onScroll, and then when you select the filter you fire this custom event to each of the filtered items.

@ghost
Copy link

ghost commented Nov 14, 2014

The jsfiddle doesn't work anymore. I am having the same issue that when you filter to a category that doesn't have any scroll bar, meaning the items are less than the window size, the items doesn't load. It's OK when there's enough space to scroll, but when you have only two or three items that is filtered and no scrollbars, it's a big problem.

I edited the fiddle with new source scripts that work. This example doesn't load the two images that was filtered. Scrolling down displays the image. Here it is

http://jsfiddle.net/vanduzled/2xcaj49m/

and here's a screencast of the problem:
http://www.screencast.com/t/uNGuKzee

@acarabott
Copy link

Have fixed the fiddle, the isotope API had been changed, and this version should work even when the imageHeight < windowHeight

http://jsfiddle.net/arthurc/ZnEhn/

@ghost
Copy link

ghost commented Nov 17, 2014

thanks for fixing the problem @acarabott. Now it works.

@flowdee
Copy link

flowdee commented Dec 28, 2014

I wrote a little snippet in order to refresh lazy load status and displaying items after using isotope filter/sort: https://gist.github.com/flowdee/b6e33d61d36bcb8323fa

@itzikbenh
Copy link

@acarabott I can't get your code to work, because I also have an item selector together with the container, where can I add it?

@acarabott
Copy link

@itzikbenh I'm not clear what you mean, can you give an example?

@itzikbenh
Copy link

@acarabott I solved it, thanks for responding. Here is the code:
As you can see I'm using an item selector and without it the isotope doesn't work so I just added that it runs every time a user scrolls.

$(window).load(function(){
$('.man').imagesLoaded( function(){
$('.man').isotope({
itemSelector : '.grid',
layoutMode: 'masonry'
});
});
});

$(window).scroll(function(){
$('.man').isotope({
itemSelector : '.grid',
layoutMode: 'masonry'
});
});

$(document).ready(function () {
$("img.lazy").lazyload({
threshold : 300
});
});

@acarabott
Copy link

Glad you resolved it 👍

@AndishehN
Copy link

AndishehN commented Jun 19, 2019

hi @itzikbenh
I have the same issue and I used your solution to solve the problem of lazy-loading, but lazy-load doesn't work and all images load immediately. do you have any suggestion for me?
thank you in advance.
this is a part of my code head:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script> 

here is my code:

     $(window).load(function(){
        $('.grid').imagesLoaded(function(){
          $('.grid').isotope({
            itemSelector: '.grid-item',
            containerClass: 'isotope',
            layoutMode: 'masonry',
            percentPosition: true   
          });
        });
      });
      $(window).scroll(function(){
        $('.grid').isotope({
          itemSelector: '.grid-item',
          containerClass: 'isotope',
          layoutMode: 'masonry',
          percentPosition: true
        });
      });

      $(document).ready(function(){
        $('.grid-item img').lazyload({
          effect: 'fadeIn',
          threshold : 300
        });
      });
.grid {
	max-width: 69em;
	list-style: none;
	margin: 20px auto;
	padding: 0;
}
.grid::after {
  content: "";
  clear: both;
  display: table;
}
.grid-sizer,
.grid-item {
	display: block;
	padding: 7px;
}
@media (min-width: 530px) {
  .grid-sizer,
.grid-item {
    float: right;
    width: 50%;
  }
}
@media (min-width: 960px) {
  .grid-sizer,
.grid-item {
    width: 33%;
  }
}

<div class="grid">
          <div class="grid-sizer"></div>
          <div class="grid-item">
            <img src="assets/images/gallery/01.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/02.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/03.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/04.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/05.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/06.JPG"/>
          </div>
          <div class="grid-item">
            <img src="assets/images/gallery/07.JPG"/>
          </div>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants