结合 LazyLoad 和 Jquery Masonry
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10096300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Combining LazyLoad and Jquery Masonry
提问by user554954
I have been trying to piece together masonry and moo tools lazyload however they both dont seem to go very well together although it possibly could just be because I am slightly useless at coding!
我一直在尝试将 masonry 和 moo 工具lazyload 拼凑在一起,但是它们似乎并没有很好地结合在一起,尽管这可能只是因为我在编码方面有点无用!
The masonry works on this page.
砌体在此页面上工作。
However when I try to put it together with lazyload it seems to totally mess up. Does anyone have any idea how to implement both plugins together?
但是,当我尝试将它与lazyload 放在一起时,它似乎完全搞砸了。有谁知道如何一起实现这两个插件?
I have spent 6 days trying to figure it out and this is my final hope ha!
我花了 6 天的时间试图弄清楚,这是我最后的希望哈!
Thanks
谢谢
回答by Nathan Do
Recently, I gotta solve this for one of my website. I have tried a couple of ways and it seems working.
最近,我必须为我的一个网站解决这个问题。我尝试了几种方法,它似乎有效。
1. First Method:
1.第一种方法:
- 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]
- 在物品上加载砌体
- 在所有图像上放置一个占位符并在它们上使用lazyload
- 现在,当每个图像触发 lazyload.load 回调时,重新加载 masonry -> 一系列 masonry('reload') [用新图像更新了 jsfiddle,更容易说明这一点]
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)
这种方法很好,但有一个缺点。网格布局可能不会保持不变,因为 masonry.reload() 的时间取决于每个图像的加载时间(即应该首先加载的可能只在稍后完成)
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:
2.第二种方法:看看像pinterest这样的网站,我认为它不遵循第一种方法,因为它们甚至在加载任何图像之前就已经排列好了容器框,因此,我试图实现的是只显示相同的框比例作为图像。步骤是:
- Pass your images dimension (just return a json like
{image1: [300,400],image2: [400,500]}
) - Use CSS trick to make div box resize according 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
- 传递您的图像尺寸(只需返回一个 json 之类的
{image1: [300,400],image2: [400,500]}
) - 使用 CSS 技巧根据容器调整 div 框的大小。我在这里找到了这个技巧
- 正常的延迟加载,从现在开始不需要触发任何重新加载,没有图像,框都排列正确
http://jsfiddle.net/nathando/s3KPn/4/
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]
[编辑为第二种方法添加jsfiddle]
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 commentdisplay: block
for#container.fluid .item img
- 在这个小提琴中,我手动在“padding-bottom: xxx%”中输入了每个图像的高/宽比,它应该从您的服务器代码中传入(请参阅第 1 步)
- 添加了边框以使框可见
- 为了说明未加载图像,即使框将被安排,尝试取消注释
/*display: none */
和评论display: block
的#container.fluid .item img
Cheers
干杯
回答by softk5
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/
http://www.webdesignleaves.com/wp/jquery/1340/
Hope this will help.
希望这会有所帮助。
The point is use following;
重点是使用以下;
$('img.lazy').load(function(){ ... })
HTML
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
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
});
});
}
回答by Ali Nouman
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.
softk5 答案对我不起作用并导致大多数浏览器冻结。这是我的以下代码,它对我有用。
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(); });
}
});
});
回答by Thomas Graft
The reason is that Masonry needs to know the dimensions of the image in order to lay out the items properly. However LazyLoad delays loading the image until the image is in the viewport, meaning that the image will have no dimensions (or have the dimensions of the dummy/placeholder image you set as the img src).
原因是 Masonry 需要知道图像的尺寸才能正确布置项目。但是 LazyLoad 会延迟加载图像,直到图像位于视口中,这意味着图像将没有尺寸(或具有您设置为 img src 的虚拟/占位符图像的尺寸)。
回答by Alexey Yakovlev
maybe someone will have problems too, hope help.
也许有人也会遇到问题,希望有所帮助。
to make it work with WordPress photoswipe-masonry theme is impossible without plugin modification.
如果不修改插件,就不可能让它与 WordPress 的 photowipe-masonry 主题一起使用。
next is related to this modification and just with masonry
下一个与此修改有关,仅与砖石有关
a) lazyload use data-original="xxx" attribute to set image url . NOT src . to you need place some placeholder . may be 1x1 pixel that will be loaded without lazyload .
a)lazyload 使用 data-original="xxx" 属性来设置图片 url 。不是 src 。你需要放置一些占位符。可能是 1x1 像素,将在没有 lazyload 的情况下加载。
b) this placeholder needs to cover ALL space for future lazyloaded image, OR masonry will make all images visible as lazyloading view. it's because before images loaded it has zero size 0px x 0px . and all images fit in the visible area before loading. Lazyload count all as visible and load all.
b) 这个占位符需要为未来的延迟加载图像覆盖所有空间,或者砌体将使所有图像作为延迟加载视图可见。这是因为在加载图像之前,它的大小为零 0px x 0px 。并且所有图像在加载前都适合可见区域。延迟加载将所有视为可见并加载所有。
to arrange ALL space for the future image you need a set
为未来的图像安排所有空间,您需要一套
style="width:xxpx;height:xxpx;"
样式=“宽度:xxpx;高度:xxpx;”
just width="xx" and height="xx" is not enough
仅 width="xx" 和 height="xx" 是不够的
so image placeholder became as :
所以图像占位符变成了:
<img src="http:..1x1px" data-original="http://real_image" style="width:xxpx;height:xxpx;">
then apply lazy load normal way and masonry. in any order.
然后应用延迟加载正常方式和砌体。以任何顺序。
Important - masonry update width to its column size, BUT not height, so if your column size = 50px, then you need to calculate heigh of placeholder
重要 - 砌体更新宽度为其列大小,但不是高度,因此如果您的列大小 = 50px,那么您需要计算占位符的高度
new_height = 50 / actual_width * actual_height;
新高度 = 50 / 实际宽度 * 实际高度;
so for WordPress theme need
所以对于 WordPress 主题需要
$scaled_height =$options['thumbnail_width']/$full[1] * $full[2];
.....
.....
<img src="http://xxxx/1x1px.jpg" data-original='. $thumb[0] .' itemprop="thumbnail" alt="'.$image_description.'" style="width:'.$full[1].'px;height:'.$scaled_height.'px;" width="'.$full[1].'" height="'.$full[2].'"/>
....
....
then add new lines below masonry init
然后在 masonry init 下面添加新行
var reloading = false;
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js',function(){
$('.msnry_item img').lazyload({
effect: 'fadeIn',
//container: container,
threshold : 200,
skip_invisible : false,
failure_limit : 5,
load: function() {
if( ! reloading ) {
reloading = true;
setTimeout(function(){
container.masonry('reload');
reloading = false;
}, 500);
}
}
});
});
回答by Rakesh
Try to re-use "Masonry" in the "callback_loaded" of the LazyLoad
尝试在LazyLoad的“ callback_loaded”中重新使用“ Masonry”
var ll = new LazyLoad({
elements_selector: "img[data-src]",
callback_loaded() {
masonry = new Masonry(grid, {
itemSelector: '.img-selector',
});
}
});
Further added code is below
进一步添加的代码如下
callback_loaded() {
masonry = new Masonry(grid, {
itemSelector: '.img-selector',
});
}