炫酷的jquery瀑布流

最近做了一个瀑布流效果,思路很简单

首先计算屏幕一行可以放多少个图片,然后在第二行开始,计算每一列的高度并取出最小值,将新图片加载在最小列高度下,如此循环,并且设定一个条件,当滑动到一定距离后,开始重新加载。当然中间我们可以加上一些动画效果,让网页看起来更炫酷一些。    

html'比较简单,这里用了li元素,给每个li外围设置了padding,内部容器设定颜色,以达成元素间隔效果,这样避免了使用maring元素最后一个还要特殊处理,当然我们还可以通过给ul设置负的margin值来解决这个问题,不过由于后面要进行很多处理所以设置了padding。

<div class="container">
<ul>
 <!-- <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/1.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
   <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/2.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/3.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/4.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/5.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/6.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/7.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/8.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/9.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/10.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>
  <li>
    <div class='wrap'>
      <div class="img">
         <img src="images/11.jpg" />
      </div>
      <div class="text">瀑布流测试demo</div>
    </div>
  </li>-->
  
  
</ul>
</div>

中间的li列表隐藏掉了,可有可无,效果都一样。

下面主要是js;

var number=0;
    var sindex=0;
    var arr=[];                                      //存放每列高度的数组
var data = [
                {'src':'1.jpg','title':'瀑布流测试'},
                {'src':'2.jpg','title':'瀑布流测试'},
                {'src':'3.jpg','title':'瀑布流测试'},
                {'src':'4.jpg','title':'瀑布流测试'},
                {'src':'5.jpg','title':'瀑布流测试'},
                {'src':'6.jpg','title':'瀑布流测试'},
                {'src':'7.jpg','title':'瀑布流测试'},
                {'src':'8.jpg','title':'瀑布流测试'},
                {'src':'9.jpg','title':'瀑布流测试'},
                {'src':'10.jpg','title':'瀑布流测试'},
                {'src':'11.jpg','title':'瀑布流测试'}
              ];

第一步设定了变量,number为每个元素的索引,arr为存储每列高度数组,并通过data数组来模拟加载。calc是执行计算的函数。

 1 window.onscroll=function(){        
 2         if($(window).scrollTop()+$(window).height()+20>$(document).height()){
 3         //alert(23)
 4             $.each(data,function(i,val){
 5                 var sHtml='<li><div class="wrap"><div class="img"><img src="images/'+val.src+'"/></div>'
 6                 sHtml+='<div class="text">'+val.title+number+'</div></div></li>'
 7                 $("ul").append(sHtml)
 8                 number++                
 9             })
10             calc()
11         }
12     }
13     window.onload=function(){            
14         //alert(23)
15             $.each(data,function(i,val){
16                 var sHtml='<li><div class="wrap"><div class="img"><img src="images/'+val.src+'"/></div>'
17                 sHtml+='<div class="text">'+val.title+number+'</div></div></li>'
18                 $("ul").append(sHtml)
19                 number++                
20             })
21             setTimeout(calc,10)        
22     }

在页面加载,页面滚动到下部时,我们循环生成li元素,并且执行calc方法,在页面加载时,对calc函数进行了延时处理,如果直接执行,会出现计算错误,不知道还有没有更好的办法解决。

 1 function calc(){                        
 2         var $_li=$('li');
 3         var length=$_li.length;
 4         var li_width=$("li").eq(0).outerWidth();
 5         var pad_width=$("li").eq(0).width();
 6         var documentWidth=$(window).width();
 7         var column=Math.floor(documentWidth/li_width);   //每一行可显示的图片数
 8         $("ul").css("width",column*li_width) ;           //计算外围容器宽度                          
 9           for(i=sindex;i<length;i++){            
10               if(i<column){                                //第一列图片正常排列
11                   arr[i]=$_li.eq(i).outerHeight();
12                   $_li.eq(i).css({"position":'absolute',                         //元素设为绝对定位
13                         "left":i*li_width,
14                         "top":100,
15                         "opacity":"0",
16                         'width':"0px"                    
17                         }).addClass("ani")
18                   $_li.eq(i).animate({
19                            opacity:"1",
20                            top:"0px",
21                            left:i*li_width, 
22                            width:pad_width                 
23                   },700)                              
24               }else{                         
25                   var minHeight=Math.min.apply(null,arr)  //计算最小高度确定位置
26                   //console.log(arr)                      
27                   var index=compare(minHeight,arr);    
28                   put($_li,i,index,column,minHeight)
29                   arr[index]+=$_li.eq(i).outerHeight()                 
30               }    
31               console.log(minHeight)          
32         }
33         sindex=length
34         
35     }

主要的元素,calc元素,通过屏幕宽度与li宽度进行每行可放置li的数量,其中第一行的元素直接赋值,每个元素的left为别为i*300,其中有些属性查了些资料才弄清楚。

jquery中获取元素宽度为width(),这个宽度只包括元素的width部分,而outerWidth()获取的宽度包括元素的padding与border,outerWidth(true)则默认包括margin。

在js中对应为offsetWidth。

获取元素相对于文档(document)的距离在jquery方法分别为offset().top,offset().left,js中为offsetHeight,offsetLeft。

在排列过程,我添加了透明度+top值得动画,同时运用css3属性进行了反转动画(scale(-1,1)效果等同于rotateY(180)).

在calc中运用了方法compare与put。如下:

 1 function compare(height,sum){        
 2         var $_length=sum.length;
 3         for(j=0;j<$_length;j++){
 4             if(sum[j]==height){
 5                return j
 6             }
 7         }
 8     }
 9     function put(obj,index,minIndex,column,height){
10         obj.eq(index).css({"position":'absolute',                         //元素设为绝对定位
11                         "left":obj.eq(Math.floor(column/2)).css("left"),
12                         "top":parseInt(height)+100,
13                         "opacity":"0",
14                         'width':"0px"                    
15                         }).addClass("ani")
16         obj.eq(index).stop().animate({
17                  opacity:"1",
18                  top:height,
19                  left:obj.eq(minIndex).css("left"), 
20                  width:"280px"                 
21         },700)                
22     }

css写的比较随意:

<style>
*{margin:0px;padding:0px}
body,html{background-color:#F5F5DC}
.container{margin:0px auto}
ul{margin:20px auto;width:auto;position:relative}
li{list-style-type:none;width:280px;padding:10px;float:left;margin-top:10px}
.wrap{background-color:#fff;box-shadow:5px 5px 10px #ccc;border-radius:10px;}
.img{padding:10px}
.img img{width:260px;border-radius:10px}
.text{height:40px;line-height:40px;text-align:center;font-family:"微软雅黑";font-size:18px}
.img img:hover{-webkit-animation:fadein ease-in-out 1s;-moz-animation:fadein ease-in-out 1s;-ms-animation:fadein ease-in-out 1s;-o-animation:fadein ease-in-out 1s}
.ani{-webkit-animation:scale 1s ease-in-out;-moz-animation:scale 1s ease-in-out;-ms-animation:scale 1s ease-in-out;-o-animation:scale 1s ease-in-out}
@-webkit-keyframes fadein{
    0%{opacity:1}
    20%{opacity:0.5}
    100%{opacity:1}
}
@-moz-keyframes fadein{
    0%{opacity:1}
    20%{opacity:0.5}
    100%{opacity:1}
}
@-ms-keyframes fadein{
    0%{opacity:1}
    20%{opacity:0.5}
    100%{opacity:1}
}
@-o-keyframes fadein{
    0%{opacity:1}
    20%{opacity:0.5}
    100%{opacity:1}
}
@-webkit-keyframes scale{
    0%{-webkit-transform:scale(-1,1)}
    50%{-webkit-transform:scale(1,1)}
}
@-moz-keyframes scale{
    from{-moz-transform:scale(-1,1)}
    to{-moz-transform:scale(1,1)}
}
@-ms-keyframes scale{
    from{-ms-transform:scale(-1,1)}
    to{-ms-transform:scale(1,1)}
}
@-o-keyframes scale{
    from{-o-transform:scale(-1,1)}
    to{-o-transform:scale(1,1)}
}
</style>

本来想按面向对象方向写,写着写着又写成了乱七八糟,没有专门学过编程,还是非常欠缺这个细胞的a ,努力吧!

有错误欢迎随时指出。

另自己新建立了一个qq群:85530789,欢迎志同道合的朋友一起多多交流技术。(现在好多技术群基本都聊不了多少真正的技术话题,失望了)

 

posted @ 2015-07-25 15:52  走在起点  阅读(1847)  评论(2编辑  收藏  举报