瀑布流布局+无限滚动加载特效

发布时间:2015-10-08 15:33 | 人气数:371
基于JQUERY(masonry+imagesloaded+infinitescroll)实现瀑布流形式的页面,并能无限滚动加载展示。

JQUERY:http://jquery.com/download/ 不解释
masonry:http://masonry.desandro.com/ 瀑布流插件
imagesloaded:http://imagesloaded.desandro.com/ 判断图片加载完成后执行JS操作
infinitescroll:http://www.infinite-scroll.com/ 无限滚动加载插件

下面,我们从其原理来讲解它们的使用,以帮助你更好的发挥它的功效。但为了快速实现,我们不讲解它们的全部内容。

页面加载相关插件(文章后面附件打包下载):

<script type="text/javascript" src="/skin/js/jquery.min.js"></script>
<script src="/skin/js/masonry.pkgd.min.js"></script>
<script src="/skin/js/imagesloaded.pkgd.min.js"></script>
<script src="/skin/js/jquery.infinitescroll.js"></script>

1. 合理的HTML布局是问题的基本

在一些案例中,由于HTML布局的差错(特别是在WordPress中),导致无限拖的失败。我们来看看比较合理的HTML结构

<div id="container">
  <div class="item">...</div>
  <div class="item w2">...</div>
  <div class="item">...</div>
  ...
</div>
<div id="page-navi">...</div>
分页page-navi包含下一页的地址即可,如<a href="/html/index_2.html">加载更多…</a>infinitescroll会自动增加下一页数据。

注意:上面的#container和#page-navi被分开,#container的任务就包含瀑布流列表,翻页的工作交给#page-navi来完成。

不少案例中,#container内的结构不规律,有一些杂项,甚至把#page-navi也放在里面,这是导致后面处理中出错的根源。

2. 存在图片时masonry+imagesloaded搭配使用

在图片出现在.item中时,我们必须等到图片加载完成再来执行masonry,否则masonry会按照图片还没加载的高度来给.item赋予高度,这结果可想而知,就是错乱感。

而使用imagesloaded则可以避免这种情况,imagesloaded会检查#container中的图片是否加载完成,只有当图片都加载完了,才会执行回调中的代码。所以,如果小白要想在存在图片的时候实现瀑布流,就必须等到图片加载完了再来使用masonry。当然,有些人不用imagesloaded,他们牛皮哄哄的使用window.load,但是这样的话会等很久很久,假如网速慢,图片加载了半天没有加载完,瀑布流就永远不会出来。所以,我在使用代码的时候都是这样使用的:
$('#container').imagesLoaded( function() {
    new Masonry( document.getElementById('container'),{itemSelector:'.item'} );
});
在分页DIV下最好直接添加以下代码,第一次图片加载完成时执行瀑布流特效,以免错位。
<script type="text/javascript">
$('#container').imagesLoaded( function(){
  $('#container').masonry({
  itemSelector: '.item',
  isFitWidth: true
  });
});
</script>
这种用法非常奇怪,官方说你可以用jQuery的方法啦,可以用$('#container').masonry({itemSelector:'.item'});就可以啦但是你要这样思考,jQuery的$()是即时获取,一个node加载好就马上获取的,这可不是什么好事,就像ready和load一样有的时候ready好了,但是还没有load,这就是图片的情况!图片ready就是加载一个标签,秒秒钟的事,但是要load却要花大把的时间和流量才行。

而如果你的列表中全部都是文字,那么就不用考虑这些了,因为文字真的就是ready可以完成的事。

3.让infinitescroll执行完,获得加载完的节点

必须等到要加载的所有的内容都加载还了,甚至加载过来的图片也已经搞定了,才开始行动。就像上面那段代码一样,如果你加载过来了一堆图片,但是图片还没有load,仅仅是ready好了,你就开始执行masonry,那么重新加载masonry就会因为从后面一页抓取的图片还没有load,而无法确定.item的高度,最后有可能让这些新加载的.item跑到#container的顶部。我想这个情况绝大部分的小白都遇到过。

如果你深刻理解了这里,你就会觉得上面那段短短的,看上去奇怪的代码,是多么精妙。

把它放在infinitescroll的执行完回调函数中。
$('#container').infinitescroll({
    navSelector : '#page-navi',
    nextSelector : '#page-navi a.next',
    itemSelector : '#container .item'
    // .. 省去了其他参数
},function(arrayOfNewElems){
    $(arrayOfNewElems).appendTo('#container');
    $('#container').imagesLoaded( function() {
        new Masonry( document.getElementById('container'),{itemSelector:'.item'} );
    });
    // .. 省去了其他动作
});
本文章示例代码,加在<HEAD>标签中,测试通过:
<script type="text/javascript">
$(document).ready(function (){  
  $("#container").infinitescroll({  
        navSelector: "#page-navi",    //分页DIV
        nextSelector: "#page-navi a", //分页DIV中的下一页链接地址
        itemSelector: ".item" ,       //#container下的瀑布流元素
        loadingImg  : "/skin/images/ajax-loader.gif", //加载动画图片,可不设置
        loadingText : "加载中...",  //加载时的显示文字,可不设置
        animate     : true,        //加载动画,默认无
        },function(arrayOfNewElems){ //回调函数,获取数据后执行
          $(arrayOfNewElems).appendTo('#container');
          $('#container').imagesLoaded( function(){ //图片加载完成后执行瀑布流布局
            new Masonry( document.getElementById('container'),{itemSelector:'.item', isFitWidth: true} );
          });
    });  
});
</script>
这样的一个逻辑就非常清晰的瀑布流布局+无限滚动加载特效完成了,源文件.rar

关键词:瀑布流布局,无限滚动,imagesloaded,masonry,infinitescroll