可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm working on this website
The products on the center and right column
are in a masonry
container.
The problem I have is that If I apply the lazy load
plugin to it, since it has different heights the images overlaps the others container:
This is how it looks (when not using lazy load):
Any ideas on how to make it work?
This is my script:
Posts.prototype.onBeforeRender = function() { var container; /* log("Msnry!"); */ container = document.querySelector('#products_tmpl'); App.msnry = new Masonry(this.el, { itemSelector: '.product', columnWidth: container.querySelector('.column-width'), gutter: container.querySelector('.gutter-sizer'), transitionDuration: '0.1s' }); return delay(1000, this.reRenderLayout); }; jQuery(function() { jQuery("img.lazy").lazyload({ effect : "fadeIn" }); }); Post.prototype.returnImageForPost = function(maxSize) { var image_url, thumbnail_images; image_url = ""; if (this.model.get("thumbnail_images") != null) { thumbnail_images = this.model.get("thumbnail_images"); thumbnail_images = _.sortBy(thumbnail_images, function(item) { return -item.width; }); _.each(thumbnail_images, function(thumb) { if (thumb.width >= maxSize) { return image_url = thumb; } }); } return image_url; };
This is the markup of each item:
<div class="product"> <div class="image"> <img class="lazy" data-original="<%= post_item.image_url.url %>"> </div> <div class="obra_meta"> <span class="nombre_artista"><%= item.title %></span> <span class="nombre_obra"><%= title %></span> </div> </div>
回答1:
You should probably recalculate the heights of the product-divs after images have been loaded. You can add a load
parameter to your lazyload
function, like so:
jQuery(function() { jQuery("img.lazy").lazyload({ effect : "fadeIn", load : adjustHeights }); });
Since your product divs are absolute, you have to set their position yourself. The function to adjust heights should therefore be something like this:
function adjustHeights() { var columnheight1 = 10; var columnheight2 = 10; jQuery('.product').each(function(){ //if product in left column itemheight = jQuery(this).height(); if(jQuery(this).css('left') == '0px'){ jQuery(this).css('top', columnheight1 + 'px'); columnheight1 += itemheight + 30; }else{ //if in right column jQuery(this).css('top', columnheight2 + 'px'); columnheight2 += itemheight + 30; } }); //don't forget to set post-container to the highest height if(Math.max(columnheight1, columnheight2) >0){ jQuery('.products').css('height', Math.max(columnheight1, columnheight2) + 'px'); } }
It iterates through all your images and pushes them underneath the div that is above them in each column.
EDIT
As per this fiddle
回答2:
Considering, that the best working for lazyload is when you know the image size (according to this: http://www.appelsiini.net/projects/lazyload ) , i would suggest to actually HAVE the image size.
You can get that before loading the images by PHP, check this: http://php.net/manual/en/function.getimagesize.php
Because i do not know the structure of post_item.image_url
i assume you have possibility to add additional parameters to the object, in this case - height.
Then i would update the template for post_item
object to also contains height (and width if needed), then i would update the template to:
<div class="product"> <div class="image"> <img class="lazy" data-original="<%= post_item.image_url.url %>" height="<%= post_item.image_url.height %>"> </div> <div class="obra_meta"> <span class="nombre_artista"><%= item.title %></span> <span class="nombre_obra"><%= title %></span> </div> </div>
height is also W3C compliant for images: http://www.w3schools.com/tags/att_img_height.asp