我正在为摄影师设立一个网站。它应该使用Bootstrap 3框架构建,并且他希望在一个页面上拥有超过400个图像的砖石。为了实现这一目标,LazyLoad是必须的。我现在花了几天的时间试图让LazyLoad与Desandros Masonry合作,但没有成功..
我已经尝试了所有人发现谷歌搜索的例子,但大多数帖子/网站/论坛只是重定向你,或者已经复制了这个stackoverflow答案: Combining LazyLoad and Jquery Masonry
我尝试了两种方法,但不幸的是我只得到了灰白的头发...... :(
以下是我正在处理的页面的简化实时版本:
http://nr.x10.mx
在这个例子中,我在页面加载时添加了淡入,但是由于我可以让它工作,所以将LazyLoad保留了。
此处您有FIDDLE以下
var container = document.querySelector('#ms-container');
imagesLoaded( container, function()
{
var msnry = new Masonry(container,
{ itemSelector: '.ms-item',
columnWidth: '.ms-item',});
});
您也可以在此处下载整个包,包括jquery.lazyload.js
HERE
任何帮助都将受到高度赞赏
更新
在这里,您可以找到4个不同问题的不同示例。
我也很高兴Bootstrap .img-responsive
课程干扰了LazyLoad。
1 - Masonry without LazyLoad
2 - Masonry and Lazyload - Masonry breaks down and LazyLoad has no effect
3 - LazyLoad without Masonry - LazyLoad has no effect
4 - LazyLoad without Masonry and Bootsrap "img-responsive" removed
5 - Masonry & LazyLoad using first method of SO answer mentioned above
6 - Masonry & LazyLoad using second method of SO answer mentioned above
两个最后的错误都会出现以下错误:[错误] TypeError:'undefined'不是函数(评估'$ container.imagesLoaded')
全球代码(5.html,第110行)
更新了zip HERE
再次,任何asisstance将非常感谢,谢谢
答案 0 :(得分:7)
我使用您发布的fiddle上显示的SO link的javascript文件,通过Nathan Do回答,使您的5.html工作。所以你可能只是使用了糟糕的脚本版本。
该页面上链接的脚本为:http://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.js
和http://cdn.jsdelivr.net/jquery.lazyload/1.8.4/jquery.lazyload.js
以下是使用该页面方法更新的原始小提琴:http://jsfiddle.net/L9RLe/
答案 1 :(得分:3)
在您的情况下,虽然您正在创建砌体并添加延迟效果,但图像会重叠。
您需要按照以下步骤操作:
为图像创建动态HTML结构及其各自的宽高比高度和宽度。注意:图像应具有应用延迟加载效果所需的属性,即class =“lazy”data-original =“actual image url”和src =“dummy imageurl”。
应用延迟加载效果。
然后创建Masonry。
让我们举个例子:
假设我有一个带有一些图像相关数据的javascript数组,
var gallery_itemList= [
{url: "images/example1.jpg", width:"1170", height:"460"},
{url: "images/example2.jpg", width:"800", height:"320"},
{url: "images/example3.jpg", width:"1200", height:"870"}];
在创建动态html的原型下,应用lazyload效果并创建Masonry效果:
var masonryGallery = {
gallery :'', // gallery to create
genarateGallery : function() {
// generate each item html
var inHTML="", i;
for(i=0;i<gallery_itemList.length;i++){
var iWidth, iHeight, fHeight=0;
iWidth=parseInt(gallery_itemList[i].width);
iHeight=parseInt(gallery_itemList[i].height);
fHeight = Math.round((iHeight*300)/iWidth);
inHTML+='<div class="item" style="height:'+fHeight+'px">';
inHTML+='<img class="lazy" src="images/loading.gif" data-original="'+gallery_itemList[i].url+'"/>';
inHTML+='</div>';
}
//add generated html to gallery
$(masonryGallery.gallery).append(inHTML);
},
applyLazyload : function(){
$("img.lazy").lazyload();
},
createMasonry : function(){
// create Masonry
$(masonryGallery.gallery).masonry({
columnWidth: 350,
itemSelector: '.item',
isFitWidth: true,
isAnimated: !Modernizr.csstransitions
}).imagesLoaded(function() {
$(this).masonry('reload');
});
},
init : function(givenGallery) {
masonryGallery.gallery = givenGallery; // set gallery
masonryGallery.genarateGallery(); // generate gallery html
masonryGallery.applyLazyload(); // apply lazyload effect
masonryGallery.createMasonry(); // apply masonry effect
}
};
/* Gallery Intialisation */
(function(){masonryGallery.init('div#content');})();
答案 2 :(得分:1)
如果问题图像重叠,我在下面的网站找到了解决方案,尽管它是日文版。
http://www.webdesignleaves.com/wp/jquery/1340/
重点是使用以下内容;
$('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
});
});
}
答案 3 :(得分:1)
只想为这个棘手的问题贡献我的解决方案。
基本上,每次图像延迟加载时都需要调用砌体的layout()
函数,因为当你知道它的尺寸是什么时就是这样。因此,您需要设置lazyload的load()
函数来调用masonry.layout()
。这可能会导致出现新问题,因为在初始页面加载时,所有图像的高度都为零或接近零(取决于您的css),因此会叠加在视口的顶部。初始化lazyload时,它将在视口中看到所有这些图像,并尝试一次加载它们。这会导致您下载大量图像,更糟糕的是,这些图像会被称为数十次或数百次。不是很快。
我的解决方案是在卸载的图像上强制最小高度,直到它们被延迟加载。这会限制最初在视口中找到的图像数量,将延迟加载和砌量调用的数量限制为合理的数量。
加载图像后,删除.unloaded
类以解除高度并使其符合图像的高度。
<div id="masonry-container">
<div class="masonry-item unloaded"><img class="lazy" data-original="image.jpg"></div>
<!-- Repeat as needed -->
</div>
.masonry-item {
width: 33.3%; // I'm doing a 3-column masonry layout
}
.unloaded {
min-height: 200px;
// set a minimum default height for image containers
// this prevents too many images from appearing in the viewport
// thus causing lazy load to load too many images at once
// we will use the lazyload .load() callback to remove this fixed
}
$( document ).ready(function() {
// Initialize Masonry
var container = document.querySelector('#masonry-container');
var msnry = new Masonry( container, { transitionDuration: 0 } );
msnry.layout(); // run masonry for first time
function doMasonry() { msnry.layout(); } // gives us a function handler to call later with window.setTimeout()
// Initialize lazyload
$("img.lazy").lazyload({
effect : "fadeIn", // optional
load : function() {
$(this).parent().removeClass("unloaded"); // select the div containing the image and remove the "unloaded" class, thus deconstricting the min-height
window.setTimeout(doMasonry,100); // trigger masonry again with a 100 ms delay, if we do it too soon, the image may not have loaded, and masonry will layout with the wrong image dimensions (this might be a bit of a hacky way to do it)
}
});
});