简体   繁体   English

Masonry&LazyLoad不想一起工作

[英]Masonry & LazyLoad doesn't want to work together

I am setting up a site for a photographer. 我正在为摄影师建立一个网站。 It should be built using the Bootstrap 3 framework, and he wants to have a masonry with over 400 images on one page. 它应该使用Bootstrap 3框架构建,并且他希望在一个页面上拥有超过400个图像的砖石。 For this to work LazyLoad is a must. 为了工作, LazyLoad是必须的。 I have now spent several days trying to get LazyLoad to work with Desandros Masonry but with no success.. 我现在花了几天时间试图让LazyLoadDesandros Masonry合作,但没有成功..

I've tried all of the examples that one finds googling, but most posts/sites/forums just redirects you, or have copied this stackoverflow answer: Combining LazyLoad and Jquery Masonry 我已经尝试了所有人发现谷歌搜索的例子,但大多数帖子/网站/论坛只是重定向你,或者已经复制了这个stackoverflow答案: 组合LazyLoad和Jquery Masonry

I've tried both methods but unfortunately I get nothing but grey hair..... :( 我尝试了两种方法,但不幸的是我只得到了灰白的头发..... :(

Here is a simplified live version of the page im working on: 这是我正在处理的页面的简化实时版本:
http://nr.x10.mx http://nr.x10.mx
In this example I have added a fade-in on page-load, but left the LazyLoad out since I can get it to work. 在这个例子中,我在页面加载时添加了一个淡入,但是因为我可以让它工作,所以留下了LazyLoad

And here you have a FIDDLE of the following 在这里你有一个以下的FIDDLE

var container = document.querySelector('#ms-container');
imagesLoaded( container, function() 
{
   var msnry = new Masonry(container, 
                                     { itemSelector: '.ms-item',
                                       columnWidth: '.ms-item',});
}); 

You can also download the whole pack here, including the jquery.lazyload.js HERE 您也可以在这里下载整包,包括jquery.lazyload.js HERE

Any help would be highly appreciated 任何帮助将受到高度赞赏


UPDATE UPDATE

Here you can have 4 different examples of the different problems that occur. 在这里,您可以找到4个不同问题的不同示例。 I also found to my joy that the Bootstrap .img-responsive class is interfering with LazyLoad. 我也很高兴Bootstrap .img-responsive类干扰了LazyLoad。

1 - Masonry without LazyLoad 1 - 没有LazyLoad的砌体
2 - Masonry and Lazyload - Masonry breaks down and LazyLoad has no effect 2 - Masonry和Lazyload - 砌体破裂,LazyLoad没有效果
3 - LazyLoad without Masonry - LazyLoad has no effect 3 - 没有砌体的LazyLoad - LazyLoad没有效果
4 - LazyLoad without Masonry and Bootsrap "img-responsive" removed 4 - LazyLoad没有砌体和Bootsrap“img-responsive”被删除
5 - Masonry & LazyLoad using first method of SO answer mentioned above 5 - Masonry&LazyLoad使用上面提到的SO答案的第一种方法
6 - Masonry & LazyLoad using second method of SO answer mentioned above 6 - Masonry&LazyLoad使用上面提到的SO答案的第二种方法
Both of the last ones gives the following error: [Error] TypeError: 'undefined' is not a function (evaluating '$container.imagesLoaded') global code (5.html, line 110) 最后两个都给出了以下错误:[错误] TypeError:'undefined'不是一个函数(评估'$ container.imagesLoaded')全局代码(5.html,第110行)

Updated zip HERE 这里更新了拉链

Again, any asisstance would be highly appreciated, thank you 再次,任何asisstance将非常感谢,谢谢

I made your 5.html work by using the javascript files of the fiddle present on the SO link you posted, answered by Nathan Do . 我使用你发布的SO链接上的小提琴的javascript文件制作你的5.html作品,由Nathan Do回答。 So you probably just had bad versions of the scripts. 所以你可能只是有不良版本的脚本。

The scripts linked on that page are: http://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.js and http://cdn.jsdelivr.net/jquery.lazyload/1.8.4/jquery.lazyload.js 在该页面上链接的脚本是: http://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.jshttp://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.jshttp://cdn.jsdelivr.net/jquery.lazyload/1.8.4/jquery.lazyload.js

Here's your original fiddle updated with that page's method: http://jsfiddle.net/L9RLe/ 这是您使用该页面方法更新的原始小提琴: http//jsfiddle.net/L9RLe/

In your case, though you are creating masonry and adding lazyload effect, the images get overlapped. 在您的情况下,虽然您正在创建砌体并添加延迟效果,但图像会重叠。

You need to follow steps as : 您需要按照以下步骤操作:

  1. Create Dynamic HTML structure for images along with their respective aspect ratio height and width. 为图像创建动态HTML结构及其各自的宽高比高度和宽度。 Note: images should have the required attributes for applying lazy load effect ie class="lazy" data-original="actual image url" and src="dummy imageurl". 注意:图像应具有应用延迟加载效果所需的属性,即class =“lazy”data-original =“actual image url”和src =“dummy imageurl”。

  2. Apply lazy load effect. 应用延迟加载效果。

  3. Then create Masonry. 然后创建砌体。

Lets have an example : 让我们举个例子:

Suppose I am having a javascript array with some image related data as, 假设我有一个带有一些图像相关数据的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"}];

And below prototype for creating dynamic html, applying lazyload effect and creating Masonry effect as : 在创建动态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');})(); 

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/

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

Just want to contribute my solution to this thorny problem. 只想为这个棘手的问题贡献我的解决方案。

Basically you need to call masonry's layout() function every time an image is lazyloaded, because that's when you know what it's dimensions are going to be. 基本上,每次图像延迟加载时都需要调用masonry的layout()函数,因为当你知道它的尺寸是什么时就是这样。 So you setup lazyload's load() function to call masonry.layout() . 所以你设置lazyload的load()函数来调用masonry.layout() This can cause a new problem, because on your initial page load, all of your images will have a zero or near-zero height (depending on your css), and thus stack up in the top of the viewport. 这可能会导致出现新问题,因为在初始页面加载时,所有图像的高度都为零或接近零(取决于您的css),因此会叠加在视口的顶部。 When you initialize lazyload, it will see all these images in the viewport, and try to load them all at once. 初始化lazyload时,它将在视口中看到所有这些图像,并尝试一次加载它们。 This causes you to download tons of images, and even worse, calls masonry dozens or hundreds of times. 这会导致您下载大量图像,更糟糕的是,这些图像会被称为数十次或数百次。 Not very speedy. 不是很快。

My solution is to force a minimum height on unloaded images until they are lazyloaded. 我的解决方案是在卸载的图像上强制最小高度,直到它们被延迟加载。 This restricts the number of images that will be found in the viewport initially, limiting the number of lazyload and masonry calls to a reasonable amount. 这会限制最初在视口中找到的图像数量,将延迟加载和砌量调用的数量限制为合理的数量。

Once an image is loaded, you remove the .unloaded class in order to deconstrict the height and allow it to conform to the height of the image. 加载图像后,删除.unloaded类以解除高度并使其符合图像的高度。

HTML HTML

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

CSS 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 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)
        }
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM