`
IT男男
  • 浏览: 14622 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

jquery瀑布流插件

 
阅读更多
/**
2  ************************************************************
3  ***@project jquery瀑布流插件
4  ***@author hcp0209@gmail.com
5  ***@ver version 1.0
6  ************************************************************
7  */
8 ;(function($){
9    var
10    //参数
11    setting={
12       column_width:204,//列宽
13       column_className:'waterfall_column',//列的类名
14       column_space:10,//列间距
15       cell_selector:'.cell',//要排列的砖块的选择器,context为整个外部容器
16       img_selector:'img',//要加载的图片的选择器
17       auto_imgHeight:true,//是否需要自动计算图片的高度
18       fadein:true,//是否渐显载入
19       fadein_speed:600,//渐显速率,单位毫秒
20       insert_type:1, //单元格插入方式,1为插入最短那列,2为按序轮流插入
21       getResource:function(index){ }  //获取动态资源函数,必须返回一个砖块元素集合,传入参数为加载的次数
22    },
23    //
24    waterfall=$.waterfall={},//对外信息对象
25    $container=null;//容器
26    waterfall.load_index=0, //加载次数
27    $.fn.extend({
28        waterfall:function(opt){
29           opt=opt||{};
30           setting=$.extend(setting,opt);
31           $container=waterfall.$container=$(this);
32           waterfall.$columns=creatColumn();
33           render($(this).find(setting.cell_selector).detach(),false);//重排已存在元素时强制不渐显
34           waterfall._scrollTimer2=null;
35           $(window).bind('scroll',function(){
36              clearTimeout(waterfall._scrollTimer2);
37              waterfall._scrollTimer2=setTimeout(onScroll,300);
38           });
39           waterfall._scrollTimer3=null;
40           $(window).bind('resize',function(){
41              clearTimeout(waterfall._scrollTimer3);
42              waterfall._scrollTimer3=setTimeout(onResize,300);
43           });
44        }
45    });
46    function creatColumn(){//创建列
47       waterfall.column_num=calculateColumns();//列数
48       //循环创建列
49       var html='';
50       for(var i=0;i<waterfall.column_num;i++){
51          html+='</pre>
52 <div class="'+setting.column_className+'" style="width: '+setting.column_width+'px; display: inline-block; *display: inline; zoom: 1; margin-left: '+setting.column_space/2+'px; margin-right: '+setting.column_space/2+'px; vertical-align: top; overflow: hidden;"></div>
53 <pre>
54 ';
55       }
56       $container.prepend(html);//插入列
57       return $('.'+setting.column_className,$container);//列集合
58    }
59    function calculateColumns(){//计算需要的列数
60       varnum=Math.floor(($container.innerWidth())/(setting.column_width+setting.column_space));
61       if(num0){//本身是图片或含有图片
62               var image=new Image;
63               var src=$(this)[0].nodeName.toLowerCase()=='img'?$(this).attr('src'):$(this).find(setting.img_selector).attr('src');
64               image.onload=function(){//图片加载后才能自动计算出尺寸
65                   image.onreadystatechange=null;
66                   if(setting.insert_type==1){
67                      insert($(elements).eq(i),setting.fadein&&fadein);//插入元素
68                   }else if(setting.insert_type==2){
69                      insert2($(elements).eq(i),i,setting.fadein&&fadein);//插入元素
70                   }
71                   image=null;
72               }
73               image.onreadystatechange=function(){//处理IE等浏览器的缓存问题:图片缓存后不会再触发onload事件
74                   if(image.readyState == "complete"){
75                      image.onload=null;
76                      if(setting.insert_type==1){
77                         insert($(elements).eq(i),setting.fadein&&fadein);//插入元素
78                      }else if(setting.insert_type==2){
79                         insert2($(elements).eq(i),i,setting.fadein&&fadein);//插入元素
80                      }
81                      image=null;
82                   }
83               }
84               image.src=src;
85           }else{//不用考虑图片加载
86               if(setting.insert_type==1){
87                  insert($(elements).eq(i),setting.fadein&&fadein);//插入元素
88               }else if(setting.insert_type==2){
89                  insert2($(elements).eq(i),i,setting.fadein&&fadein);//插入元素
90               }
91           }
92       });
93    }
94    function public_render(elems){//ajax得到元素的渲染接口
95       render(elems,true);
96    }
97    function insert($element,fadein){//把元素插入最短列
98       if(fadein){//渐显
99          $element.css('opacity',0).appendTo(waterfall.$columns.eq(calculateLowest())).fadeTo(setting.fadein_speed,1);
100       }else{//不渐显
101          $element.appendTo(waterfall.$columns.eq(calculateLowest()));
102       }
103    }
104    function insert2($element,i,fadein){//按序轮流插入元素
105       if(fadein){//渐显
106          $element.css('opacity',0).appendTo(waterfall.$columns.eq(i%waterfall.column_num)).fadeTo(setting.fadein_speed,1);
107       }else{//不渐显
108          $element.appendTo(waterfall.$columns.eq(i%waterfall.column_num));
109       }
110    }
111    function calculateLowest(){//计算最短的那列的索引
112       var min=waterfall.$columns.eq(0).outerHeight(),min_key=0;
113       waterfall.$columns.each(function(i){
114          if($(this).outerHeight()=bottom-windowHeight){
115              render(getElements(),true);
116           }
117       },100);
118    }
119    function onResize(){//窗口缩放时重新排列
120       if(calculateColumns()==waterfall.column_num) return//列数未改变,不需要重排
121       var $cells=waterfall.$container.find(setting.cell_selector);
122       waterfall.$columns.remove();
123       waterfall.$columns=creatColumn();
124       render($cells,false); //重排已有元素时强制不渐显
125    }
126 })(jQuery);

插件使用方法:

1 $(selector).waterfall(opt); //其中selector为瀑布流容器的选择器,opt为配置参数对象

所需的html结构:
html结构可以就是一个空容器元素,如

 

,里面的砖块元素通过动态加载进来。当然也可以预先放一些砖块进去,如demo页中的

1 <div id="container">
2 <div class="cell"><img src="P_000.jpg" /><p>00</p></div>
3 <div class="cell"><img src="P_001.jpg" /><p>01</p></div>
4 <div class="cell"><img src="P_002.jpg" /><p>02</p></div>
5 <div class="cell"><img src="P_003.jpg" /><p>03</p></div>
6 <div class="cell"><img src="P_004.jpg" /><p>04</p></div>
7 <div class="cell"><img src="P_005.jpg" /><p>05</p></div>
8 <div class="cell"><img src="P_006.jpg" /><p>06</p></div>
9 <div class="cell"><img src="P_007.jpg" /><p>07</p></div>
10 <div class="cell"><img src="P_008.jpg" /><p>08</p></div>
11 <div class="cell"><img src="P_009.jpg" /><p>09</p></div>
12 <div class="cell"><img src="P_010.jpg" /><p>10</p></div>
13 <div class="cell"><img src="P_011.jpg" /><p>11</p></div>
14 <div class="cell"><img src="P_012.jpg" /><p>12</p></div>
15 <div class="cell"><img src="P_013.jpg" /><p>13</p></div>
16 <div class="cell"><img src="P_014.jpg" /><p>14</p></div>
17 <div class="cell"><img src="P_015.jpg" /><p>15</p></div>
18 <div class="cell"><img src="P_016.jpg" /><p>16</p></div>
19 <div class="cell"><img src="P_017.jpg" /><p>17</p></div>
20 <div class="cell"><img src="P_018.jpg" /><p>18</p></div>
21 <div class="cell"><img src="P_019.jpg" /><p>19</p></div>
22 </div>

下面详细说下配置参数对象opt的各属性的作用及其默认值。
column_width:204 //瀑布流是由列组成的,该参数规定了每列的宽度,该参数会直接影响到瀑布流的列数
column_className:’waterfall_column’ //列的类名,便于自定义样式
column_space:10 //列与列之间的间距
cell_selector:’.cell’ //要排列的砖块的选择器,限定在瀑布流的容器内,即插件是通过这个选择器来获取砖块元素的,并且是在瀑布流的容器内来查找这个选择器匹配的元素。
img_selector:’img’ //要加载的图片的选择器。如果你的瀑布流要加载的砖块元素的主题内容是大小不固定的图片,则该参数就是这些图片的选择器,插件需要获取这些图片来进行计算。
auto_imgHeight:true //是否需要自动计算图片的高度,如果图片的大小是固定的,则把该参数设为false吧
fadein:true //是否渐显载入
fadein_speed:600 //渐显速率,单位毫秒
insert_type:1 //砖块插入方式,1为插入最短那列,2为按序轮流插入
getResource:function(index,render){ } //获取动态资源函数,必须返回一个砖块元素集合,传入的第一个参数index为已加载的次数,第二个参数为渲染函数,它可以接受一个砖头元素集合作为参数,如果是使用ajax加载数据,则得到数据后要手动调用该函数来进行渲染 。每次到达瀑布流底部时会自动触发该函数来加载更多资源。

吐槽时间:
瀑布流加载的内容一般都宽度相同,高度不同的图片,如果能预先知道图片的高度,那就简单多了,但如果不能,则必须等到图片加载后才能计算出图片的高度,这是瀑布流最烦人的地方,也正是因为这样,如果是那些不知道高度的图片,则插入的顺序可能会有些混乱,而且每次刷新顺序都不同,因为每张图片加载完成的先后顺序并不是固定的,也许这次这个快一点,下次那个快一点。所以如果图片高度事先不知道,则整个砖块的高度也会不知道,必须等砖块里的图片加载完成后才能算出砖块的高度。如果是这样但又想保证砖块的插入顺序,则建议使用按顺序轮流插入的方式插入砖块,即把insert_type参数设为2。因为是插件,所以要考虑使用简便,但使用起来越简便,插件内部就会越复杂,漏洞、bug也会增多,所以我会继续完善这个插件。
本插件支持IE6+、chrome、firefox、opera、safari等主流浏览器。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics