13

我正在为摄影师建立一个网站。它应该使用 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 这里

任何帮助将不胜感激


更新

在这里,您可以有 4 个不同示例来说明发生的不同问题。我还高兴地发现 Bootstrap.img-responsive类正在干扰 LazyLoad。

1 - 没有LazyLoad 的砌体
2 - 砌体和 Lazyload - 砌体分解并且 LazyLoad 没有效果
3 - 没有 Masonry 的 LazyLoad - LazyLoad 没有效果
4 - 没有 Masonry 和 Bootsrap 的 LazyLoad “img-responsive” 已删除
5 - 砌体和 LazyLoad 使用第一种方法上面提到的 SO 答案的
6 - Masonry & LazyLoad 使用上面提到的 SO 答案的第二种方法
最后两个都给出以下错误:[Error] TypeError: 'undefined' is not a function (evalating '$container.imagesLoaded') global代码(5.html,第 110 行)

更新 zip HERE

再次,任何帮助将不胜感激,谢谢

4

4 回答 4

7

我通过使用您发布的SO 链接上存在的小提琴的 javascript 文件使您的 5.html 工作,由Nathan Do回答。所以你可能只是有错误的脚本版本。

该页面上链接的脚本是: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/

于 2014-02-03T19:16:38.873 回答
3

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

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

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

  2. 应用延迟加载效果。

  3. 然后创建砌体。

让我们举个例子:

假设我有一个带有一些图像相关数据的 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、应用延迟加载效果和创建砌体效果的原型:

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');})(); 
于 2014-02-04T12:41:41.910 回答
1

只想为这个棘手的问题贡献我的解决方案。

基本上,每次延迟加载图像时,您都需要调用 masonry 的layout()函数,因为那时您就知道它的尺寸将是多少。所以你设置了lazyload的load()函数来调用masonry.layout(). 这可能会导致一个新问题,因为在初始页面加载时,所有图像的高度都将为零或接近零(取决于您的 css),因此会堆叠在视口的顶部。当你初始化延迟加载时,它会在视口中看到所有这些图像,并尝试一次加载它们。这会导致您下载大量图像,更糟糕的是,调用 masonry 数十或数百次。不是很快。

我的解决方案是强制卸载图像的最小高度,直到它们被延迟加载。这限制了最初将在视口中找到的图像数量,将延迟加载和砌体调用的数量限制在合理的数量。

加载图像后,删除.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)
        }
    });
});
于 2015-01-29T00:00:18.587 回答
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
        });
    });
 }
于 2015-01-04T19:50:37.260 回答