Combining LazyLoad and Jquery Masonry Combining LazyLoad and Jquery Masonry jquery jquery

Combining LazyLoad and Jquery Masonry


Recently, I gotta solve this for one of my website. I have tried a couple of ways and it seems working.

1. First Method:

  • Load masonry on the items
  • Put a place holder on all images and use lazyload on them
  • Now, when each image fire lazyload.load callback, reload masonry -> a series of masonry('reload')[Updated jsfiddle with new images, easier to illustrate the point]

http://jsfiddle.net/7vEJM/8/

var $container = $('#container');$container.imagesLoaded(function(){    $container.masonry({        itemSelector: '.item',        columnWidth: function(containerWidth){            return containerWidth / 12;        }    });    $('.item img').addClass('not-loaded');    $('.item img.not-loaded').lazyload({        effect: 'fadeIn',        load: function() {            // Disable trigger on this image            $(this).removeClass("not-loaded");            $container.masonry('reload');        }    });    $('.item img.not-loaded').trigger('scroll');});

This method is good, but it has one disadvantage. The grid layout might not be kept the same since the time of masonry.reload() depends on each image's load time (i.e. the one supposed to be loaded first might only finish later)

2. Second Method: Look at sites like pinterest, i think, it does not follow the first method, because they have the container boxes arranged even before any image loaded, therefore, what I tried to achieve is to display just the boxes with same ratio as the images. The steps are:

  • Pass your images dimension (just return a json like {image1: [300,400],image2: [400,500]} )
  • Use CSS trick to make div box resizeaccording to container. I found that trick here
  • Lazy load like normal, no need to trigger any reload since now, without the image,the boxes are alr arranged correctly

http://jsfiddle.net/nathando/s3KPn/4/

var $container = $('#container');$container.imagesLoaded(function(){    $container.masonry({        itemSelector: '.item',        columnWidth: function(containerWidth){            return containerWidth / 12;        }    });    $('.item img').lazyload({        effect: 'fadeIn'    });    $('.item img').trigger('scroll');});

[Edited to add the jsfiddle for the second method]

Notice:

  • In this fiddle, I manually put in the height/width ratio of each image in 'padding-bottom: xxx%' which should be passed in from your server code (refer to step 1)
  • Added in a border to make boxes visible
  • To illustrate that the boxes will be arranged even when the images not loaded, try uncomment /*display: none */ and comment display: block for #container.fluid .item img

Cheers


I posted the same answer on other same issues article. If you have the problem images get overlapped, I found the solution at the site below, although it is in Japanese.

http://www.webdesignleaves.com/wp/jquery/1340/

Hope this will help.

The point is use following;

$('img.lazy').load(function(){ ... })

HTML

<div id="works_list"><div class="work_item"><img class="lazy" src="images/dummy.gif" data-original="images/works/thumb/001.jpg" alt=""><p>title 1</p>  </div><!-- end of .work_item--><div class="work_item"><img class="lazy" src="images/dummy.gif" data-original="images/works/thumb/002.jpg" alt=""><p>title 2</p>  </div><!-- end of .work_item--> ....</div><!-- end of #works_list -->    

jQuery

$("img.lazy").lazyload({    effect: 'fadeIn',    effectspeed: 1000,    threshold: 200});$('img.lazy').load(function() {    masonry_update();});function masonry_update() {         var $works_list = $('#works_list');    $works_list.imagesLoaded(function(){        $works_list.masonry({            itemSelector: '.work_item',             isFitWidth: true,             columnWidth: 160        });    }); }    


softk5 answer wasn't working for me and causing freeze on the most of browser. Here is my following code and its working for me.

jQuery(document).ready(function(){    jQuery("img.lazy").lazyload({        effect: 'fadeIn',        effectspeed: 1000,        threshold: 200,        load:function(){            var $container = jQuery('.is_masonry');            $container.masonry({            }).imagesLoaded(function() {   $container.masonry();  });        }    });});