砌体和LazyLoad不想一起工作

时间:2014-01-29 14:37:20

标签: javascript jquery css jquery-masonry jquery-lazyload

我正在为摄影师设立一个网站。它应该使用Bootstrap 3框架构建,并且他希望在一个页面上拥有超过400个图像的砖石。为了实现这一目标,LazyLoad是必须的。我现在花了几天的时间试图让LazyLoadDesandros 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将非常感谢,谢谢

4 个答案:

答案 0 :(得分:7)

我使用您发布的fiddle上显示的SO link的javascript文件,通过Nathan Do回答,使您的5.html工作。所以你可能只是使用了糟糕的脚本版本。

该页面上链接的脚本为:http://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.jshttp://cdn.jsdelivr.net/jquery.lazyload/1.8.4/jquery.lazyload.js

以下是使用该页面方法更新的原始小提琴:http://jsfiddle.net/L9RLe/

答案 1 :(得分:3)

在您的情况下,虽然您正在创建砌体并添加延迟效果,但图像会重叠。

您需要按照以下步骤操作:

  1. 为图像创建动态HTML结构及其各自的宽高比高度和宽度。注意:图像应具有应用延迟加载效果所需的属性,即class =“lazy”data-original =“actual image url”和src =“dummy imageurl”。

  2. 应用延迟加载效果。

  3. 然后创建Masonry。

  4. 让我们举个例子:

    假设我有一个带有一些图像相关数据的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类以解除高度并使其符合图像的高度。

HTML

<div id="masonry-container">
    <div class="masonry-item unloaded"><img class="lazy" data-original="image.jpg"></div>
    <!-- Repeat as needed -->
</div>

CSS

.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 
}

JS

$( 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)
        }
    });
});