js瀑布流效果搭建

血红的双手。 提交于 2019-12-09 12:13:46

最终实例下载地址:http://www.oschina.net/code/snippet_2352644_55042

 

一.基本瀑布流实现

这篇博客也是实例的讲解,本来已经完成了一半,因为临时有事出去,再回来一个没注意,关闭了页面,我记得明明会自动保存的,哎!

图片放在images目录下:

1.png

2.png

3.png

4.png

5.png

6.png

7.png

8.png

9.png

10.png

11.png

12.png

再写也没有那么多动力了,我把全部代码直接粘贴,然后讲一下里面的知识和注意问题:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>瀑布流</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:480px;margin:50px auto;position:relative; border-top:5px solid #ddd;}
#box div{ width:120px; position:absolute;}
#box div img{ display:block;border:1px solid #ddd; width:100px; margin:0 8px;}
</style>
</head>
<body>
    <!--瀑布流-->
    <div id="box">
     
    </div>
    
</body>
<script type="text/javascript">
window.onload=function(){
 //瀑布流
 var box=document.getElementById("box");
 var w=120;//基本宽度
 var iw=100;//图片基本宽
 var arr_h=[0,0,0,0];//保存一行个数高度
 function init(json){//第一行处理
  var len=json.length;//获取个数
  for(var i=0;i<len;i++){
   var obj=document.createElement("div");  
   var oimg=document.createElement("img");
   oimg.src=json[i].url;//赋值路径 
   //通过实际值计算显示高度 
   oimg.height=(json[i].h/json[i].w)*iw;    
   obj.appendChild(oimg);
   obj.style.left=i*w+"px";//left来自索引*基本宽
   obj.style.top="0px"; //top第一行都为0  
   box.appendChild(obj);
   arr_h[i]=obj.offsetHeight+10;//存放当前高度     
  };
 };
 function append(json){//插入处理
  var len=json.length;//获取个数
  for(var i=0;i<len;i++){
   //获取高度最小位置   
   var minv=Math.min.apply(null,arr_h);
   var x;//保存最小位置值的索引
   for(var j=0;j<arr_h.length;j++){
    if(arr_h[j]==minv){
     x=j;
    };
   };
   //插入处理
   var obj=document.createElement("div");
   var oimg=document.createElement("img");
   oimg.src=json[i].url; //赋值路径 
   //通过实际值计算显示高度 
   oimg.height=(json[i].h/json[i].w)*iw; 
   obj.appendChild(oimg);
   obj.style.left=x*w+"px";//left来自最小索引*基本宽
   obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
   box.appendChild(obj);
   arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度
  };
 };
 //后台拿来的数据
 var json1=[
  {url:"images/1.png",w:70,h:120},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/4.png",w:185,h:116}
 ];
 var json2=[
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
 ];
 init(json1);//初始化第一行
 append(json2);//插入28个图片
 
 //滚动到最低部判断程序 
 window.onscroll=function(){
  var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    append(json_ajax);//插入16个图片
   },800);
  }else{};
 };
 
};
</script>
</html>

1.获取img的高度

obj.offsetHeight

我们可以获取到img的高度,不过img比较特殊,他的高度只有在load也就是加载完后获取,为了避免这个加载快慢问题,我们插入图片时除了拿到链接,还有拿实际宽高。

返回的数据:

var json1=[
  {url:"images/1.png",w:70,h:120},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/4.png",w:185,h:116}
 ];

除了路径,我们是定了宽度,还要按照实际图片比例计算显示高度:

oimg.src=json[i].url;//赋值路径 
   //通过实际值计算显示高度 
   oimg.height=(json[i].h/json[i].w)*iw;

2.如何判断页面滚动到底部

//滚动到最低部判断程序 
 window.onscroll=function(){
};

我们加入了页面滚动事件处理,滚动事件要监听在window或者document这种顶级对象上。

我们页面移动时其实是这样的:

sh是根元素的真实高度,ch是可见高度,我们如图获取差值,就是页面到最底部的scrolltop值。

我们利用滚动事件可以时时获取滚动条距离顶部值,加入判断:

var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
      },800);
  }else{};

相等时就是最底部时。

var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高

c获取可见高,也就是window高,s获取实际高度,滚动条滚动到最底部值+可见高值

document.documentElement

是页面的根容器,代表html元素,我们通过它计算真实高度和可见高度,因为html元素默认样式是overflow:auto。高度等于window高度。

var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌

针对谷歌兼容方案,谷歌要通过body对象获取时时距离顶部值。其实真是根是html。

3.初始数据插入

var obj=document.createElement("div"); 
var oimg=document.createElement("img");
oimg.src=json[i].url;//赋值路径 
//通过实际值计算显示高度 
oimg.height=(json[i].h/json[i].w)*iw; 
obj.appendChild(oimg);

我们根据传入的json数据,创建节点,插入处理,

obj.style.left=i*w+"px";//left来自索引*基本宽
   obj.style.top="0px"; //top第一行都为0

我们这是第一行的插入,插入了4个对象,top全部为0。left正好就是基本宽*所在索引。

0*120 1*120 2*120 3*120

arr_h[i]=obj.offsetHeight+10;//存放当前高度

保存第一行插入后,1-4个对象的高度:

然后我们插入第5个的时候,会找到最低的那一个,我们上面已经保存:

var arr_h=[0,0,0,0];//保存一行个数高度

经过第一行保存赋值以后可能变为:

var arr_h=[140,100,120,50];//保存一行个数高度

这次我们第5个对象要插入到的位置就是:

这个top值就是数组中最小那一个,我们获取到:

var minv=Math.min.apply(null,arr_h);

left其实就是最小值所在索引*基本宽,我们就要先拿到最小高度值所在索引位置

var x;//保存最小位置值的索引
   for(var j=0;j<arr_h.length;j++){
    if(arr_h[j]==minv){
     x=j;
    };
   };

然后就可以根据这个进行第5个位置设置:

obj.style.left=x*w+"px";//left来自最小索引*基本宽
   obj.style.top=arr_h[x]+"px";//top来自最小索引位置值

赋值以后,我们保存数组这个高度值就应该发生变化,变化后的值就是原有高度值+插入元素的高度

arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度

以后的每次插入,都会遍历最小高度,left就来自所在索引,然后设置位置,以此类推。

4.到最底部时加载数据

if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    append(json_ajax);//插入16个图片
   },800);
  }else{};

我们已经写好判断处理,只要达到这个位置,我们直接调用插入方法,把数据插入进去即可!

5.数据模拟问题

我们的数据都是前台设置,其实这些应该来自后台请求,

尤其是滚动加载的更是一个ajax的请求处理。

 

二.响应式瀑布流实现--自动计算单行个数

 什么是响应式,其实在css3中已经有布局手段,就是根据屏幕大小,调整我们的布局结构,我么知道我们的实例这中每个div的宽是120px,我们把他的父容器设置为480,所有就是一行放了4个。现在我们把这个父容器宽设置为百分比,加入设置为80%;

这是浏览器窗口大小是1000px,那么父容器就是800px,一行个数就是800/120 约等于6.666 其实我们一行就是可以防止6个,每次向下取整。

我们的核心原理总结如下:

1.判断浏览器窗口宽度

2.box这个父容器的宽由百分比设置,动态来自窗口

3.一行的个数等于box宽/每个所占宽度

我们先修改原有实例,做到自动判断出一行个数,而不是写死:

var box_w=box.offsetWidth;//获取容易宽
 //向下取整,获取一行个数
 var row_x=Math.floor(box_w/w);

我们输出的就是4,下面我就修改插入方法,根据这个计算的单行个数插入数据:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>瀑布流</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:480px;margin:50px auto;position:relative; border-top:5px solid #ddd;}
#box div{ width:120px; position:absolute;}
#box div img{ display:block;border:1px solid #ddd; width:100px; margin:0 8px;}
</style>
</head>
<body>
    <!--瀑布流-->
    <div id="box">
     
    </div>
    
</body>
<script type="text/javascript">
window.onload=function(){
 //瀑布流
 var box=document.getElementById("box"); 
 var w=120;//基本宽度
 var box_w=box.offsetWidth;//获取容易宽
 //向下取整,获取一行个数
 var row_x=Math.floor(box_w/w);
 var iw=100;//图片基本宽
 var arr_h=[0,0,0,0];//保存一行个数高度
 function append(json,isinit,row_x){//插入处理 isinit表明是不是初始插入 初始为true row_x被使用,显示一行处理
  if(isinit){//初始化处理
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    if(i<row_x){//第一行处理
     var obj=document.createElement("div");  
     var oimg=document.createElement("img");
     oimg.src=json[i].url;//赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw;    
     obj.appendChild(oimg);
     obj.style.left=i*w+"px";//left来自索引*基本宽
     obj.style.top="0px"; //top第一行都为0  
     box.appendChild(obj);
     arr_h[i]=obj.offsetHeight+10;//存放当前高度  
    }else{ //后续处理    
     //获取高度最小位置   
     var minv=Math.min.apply(null,arr_h);
     var x;//保存最小位置值的索引
     for(var j=0;j<arr_h.length;j++){
      if(arr_h[j]==minv){
       x=j;
      };
     };
     //插入处理
     var obj=document.createElement("div");
     var oimg=document.createElement("img");
     oimg.src=json[i].url; //赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw; 
     obj.appendChild(oimg);
     obj.style.left=x*w+"px";//left来自最小索引*基本宽
     obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
     box.appendChild(obj);
     arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度 
    };       
   };   
  }else{
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    //获取高度最小位置   
    var minv=Math.min.apply(null,arr_h);
    var x;//保存最小位置值的索引
    for(var j=0;j<arr_h.length;j++){
     if(arr_h[j]==minv){
      x=j;
     };
    };
    //插入处理
    var obj=document.createElement("div");
    var oimg=document.createElement("img");
    oimg.src=json[i].url; //赋值路径 
    //通过实际值计算显示高度 
    oimg.height=(json[i].h/json[i].w)*iw; 
    obj.appendChild(oimg);
    obj.style.left=x*w+"px";//left来自最小索引*基本宽
    obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
    box.appendChild(obj);
    arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度
   };   
  };  
 };
 //后台拿来的数据
 var json1=[
  {url:"images/1.png",w:70,h:120},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
 ];
 append(json1,true,row_x);//初始化
 
 //滚动到最低部判断程序 
 window.onscroll=function(){
  var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    append(json_ajax,false,0);//插入16个图片
   },800);
  }else{};
 };
 
};
</script>
</html>

我们把init和append融合再了一起,在内部根据true判断是否是初始化操作,是初始化操作,根据单行个数参数做第一行处理。

 

三.响应式瀑布流实现--父容器响应设置

继续上面处理,我们现在就需要按照总结的原理,把box的宽度按照百分比去设置:

#box{ width:80%;margin:50px auto;position:relative; border-top:5px solid #ddd;}

我们调整布局div大小,我们图片太少,为了方便处理。

#box div{ width:240px; position:absolute;}
#box div img{ display:block;border:1px solid #ddd; width:220px; margin:0 8px;}

此时,还有一个重要地方要做修改:

var arr_h=[];//保存一行个数高度

我们删除原有的那种赋值方式,只定义是一个数组就好了,最后会根据我们处理,自动把记录数组长度设置为一行个数值。

乎已经实现了我们的响应式处理,每次改变窗口大小后刷新查看。

我们需要的是自动判断改变了尺寸,然后就可以修改布局,而不是改变大小后必须刷新查看,我们可以借助resize事件去处理:

window.onresize=function(){
   location=location;
 };

简单粗暴,我们改变大小去触发刷新,就响应式修改了布局。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>瀑布流</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:80%;margin:50px auto;position:relative; border-top:5px solid #ddd;}
#box div{ width:240px; position:absolute;}
#box div img{ display:block;border:1px solid #ddd; width:220px; margin:0 8px;}
</style>
</head>
<body>
    <!--瀑布流-->
    <div id="box">
     
    </div>
    
</body>
<script type="text/javascript">
window.onload=function(){
 //瀑布流
 var box=document.getElementById("box"); 
 var w=240;//基本宽度
 var box_w=box.offsetWidth;//获取容易宽
 //向下取整,获取一行个数
 var row_x=Math.floor(box_w/w);
 var iw=220;//图片基本宽
 var arr_h=[];//保存一行个数高度
 function append(json,isinit,row_x){//插入处理 isinit表明是不是初始插入 初始为true row_x被使用,显示一行处理
  if(isinit){//初始化处理
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    if(i<row_x){//第一行处理
     var obj=document.createElement("div");  
     var oimg=document.createElement("img");
     oimg.src=json[i].url;//赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw;    
     obj.appendChild(oimg);
     obj.style.left=i*w+"px";//left来自索引*基本宽
     obj.style.top="0px"; //top第一行都为0  
     box.appendChild(obj);
     arr_h[i]=obj.offsetHeight+10;//存放当前高度  
    }else{ //后续处理    
     //获取高度最小位置   
     var minv=Math.min.apply(null,arr_h);
     var x;//保存最小位置值的索引
     for(var j=0;j<arr_h.length;j++){
      if(arr_h[j]==minv){
       x=j;
      };
     };
     //插入处理
     var obj=document.createElement("div");
     var oimg=document.createElement("img");
     oimg.src=json[i].url; //赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw; 
     obj.appendChild(oimg);
     obj.style.left=x*w+"px";//left来自最小索引*基本宽
     obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
     box.appendChild(obj);
     arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度 
    };       
   };   
  }else{
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    //获取高度最小位置   
    var minv=Math.min.apply(null,arr_h);
    var x;//保存最小位置值的索引
    for(var j=0;j<arr_h.length;j++){
     if(arr_h[j]==minv){
      x=j;
     };
    };
    //插入处理
    var obj=document.createElement("div");
    var oimg=document.createElement("img");
    oimg.src=json[i].url; //赋值路径 
    //通过实际值计算显示高度 
    oimg.height=(json[i].h/json[i].w)*iw; 
    obj.appendChild(oimg);
    obj.style.left=x*w+"px";//left来自最小索引*基本宽
    obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
    box.appendChild(obj);
    arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度
   };   
  };  
 };
 //后台拿来的数据
 var json1=[
  {url:"images/1.png",w:70,h:120},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
 ];
 append(json1,true,row_x);//初始化
 
 //滚动到最低部判断程序 
 window.onscroll=function(){
  var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    append(json_ajax,false,0);//插入16个图片
   },800);
  }else{};
 };
 window.onresize=function(){
   location=location;
 };
 
};
</script>
</html>

 

.响应式瀑布流完成

我们上面的处理其实不是不可以,用户以改变尺寸,不过后追加的都不见了。如果我们把后添加的保存下来,改变尺寸后作为初始数据加进去就更好了:

json1=json1.concat(json_ajax);//保存追加记录

我们拼接数组,然后把初始化用的json1二次赋值为这个新数组。

window.onresize=function(){
  box.innerHTML="";
  box_w=box.offsetWidth;//获取容易宽
  //向下取整,获取一行个数
  row_x=Math.floor(box_w/w);
  arr_h=[];//保存一行个数高度
  
  append(json1,true,row_x);//初始化
 };

我们其实也是从新设置,我们最前提就是删除box下的所有内容:

box.innerHTML="";

然后把应该布局的全部重新计算:

box_w=box.offsetWidth;//获取容易宽
  //向下取整,获取一行个数
  row_x=Math.floor(box_w/w);
  arr_h=[];//保存一行个数高度

下面就是我们完成的全部代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>瀑布流</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:80%;margin:50px auto;position:relative; border-top:5px solid #ddd;}
#box div{ width:240px; position:absolute;}
#box div img{ display:block;border:1px solid #ddd; width:220px; margin:0 8px;}
</style>
</head>
<body>
    <!--瀑布流-->
    <div id="box">
     
    </div>
    
</body>
<script type="text/javascript">
window.onload=function(){
 //瀑布流
 var box=document.getElementById("box"); 
 var w=240;//基本宽度
 var box_w=box.offsetWidth;//获取容易宽
 //向下取整,获取一行个数
 var row_x=Math.floor(box_w/w);
 var iw=220;//图片基本宽
 var arr_h=[];//保存一行个数高度
 function append(json,isinit,row_x){//插入处理 isinit表明是不是初始插入 初始为true row_x被使用,显示一行处理
  if(isinit){//初始化处理
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    if(i<row_x){//第一行处理
     var obj=document.createElement("div");  
     var oimg=document.createElement("img");
     oimg.src=json[i].url;//赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw;    
     obj.appendChild(oimg);
     obj.style.left=i*w+"px";//left来自索引*基本宽
     obj.style.top="0px"; //top第一行都为0  
     box.appendChild(obj);
     arr_h[i]=obj.offsetHeight+10;//存放当前高度  
    }else{ //后续处理    
     //获取高度最小位置   
     var minv=Math.min.apply(null,arr_h);
     var x;//保存最小位置值的索引
     for(var j=0;j<arr_h.length;j++){
      if(arr_h[j]==minv){
       x=j;
      };
     };
     //插入处理
     var obj=document.createElement("div");
     var oimg=document.createElement("img");
     oimg.src=json[i].url; //赋值路径 
     //通过实际值计算显示高度 
     oimg.height=(json[i].h/json[i].w)*iw; 
     obj.appendChild(oimg);
     obj.style.left=x*w+"px";//left来自最小索引*基本宽
     obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
     box.appendChild(obj);
     arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度 
    };       
   };   
  }else{
   var len=json.length;//获取个数
   for(var i=0;i<len;i++){
    //获取高度最小位置   
    var minv=Math.min.apply(null,arr_h);
    var x;//保存最小位置值的索引
    for(var j=0;j<arr_h.length;j++){
     if(arr_h[j]==minv){
      x=j;
     };
    };
    //插入处理
    var obj=document.createElement("div");
    var oimg=document.createElement("img");
    oimg.src=json[i].url; //赋值路径 
    //通过实际值计算显示高度 
    oimg.height=(json[i].h/json[i].w)*iw; 
    obj.appendChild(oimg);
    obj.style.left=x*w+"px";//left来自最小索引*基本宽
    obj.style.top=arr_h[x]+"px";//top来自最小索引位置值
    box.appendChild(obj);
    arr_h[x]=arr_h[x]+obj.offsetHeight+10;//存放变化后当前高度
   };   
  };  
 };
 //后台拿来的数据
 var json1=[
  {url:"images/1.png",w:70,h:120},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/12.png",w:150,h:100},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
  {url:"images/6.png",w:148,h:114},
  {url:"images/5.png",w:188,h:107},
  {url:"images/2.png",w:98,h:108},
  {url:"images/3.png",w:106,h:145},
  {url:"images/1.png",w:70,h:120},
  {url:"images/4.png",w:185,h:116},
  {url:"images/11.png",w:150,h:187},
  {url:"images/10.png",w:148,h:132},
  {url:"images/9.png",w:152,h:110},
  {url:"images/8.png",w:109,h:123},
  {url:"images/7.png",w:95,h:142},
 ];
 append(json1,true,row_x);//初始化
 //滚动到最低部判断程序 
 window.onscroll=function(){
  var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    json1=json1.concat(json_ajax);//保存追加记录
    append(json_ajax,false,0);//插入16个图片
   },800);
  }else{};
 };
 
 window.onresize=function(){
  box.innerHTML="";
  box_w=box.offsetWidth;//获取容易宽
  //向下取整,获取一行个数
  row_x=Math.floor(box_w/w);
  arr_h=[];//保存一行个数高度  
  append(json1,true,row_x);//初始化
 };
 
};
</script>
</html>

 

最终实例下载地址:http://www.oschina.net/code/snippet_2352644_55042

 

.css3多栏属性实现瀑布流

我们上面都是js的实现,js的处理我们含有很多计算处理,相对耗内存,我们css3的出现,尤其是多栏属性,在不考虑低级浏览器情况的,这种实现就是福音。

-moz-columns:240px;
-webkit-columns:240px;
columns:240px;

设置一栏宽度为240px,那么我们的box就会被按这个分割:

我们的box就和刀切一样,每一条都是240px大小,切完以后,下面的子元素就会把切完的作为布局容器去防止进去,如图一样,我们子元素都是240px的,都以切好的每一栏做容器插进去,就实现了瀑布流效果。而且多栏设置后下面子元素是按照css3的算法布局,非常的快。

下面是去全部代码,简单优雅,无延时显示:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>瀑布流</title>
    <style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#box{ width:80%;margin:50px auto;border-top:5px solid #ddd;
-moz-columns:240px;
-webkit-columns:240px;
columns:240px;
}
#box div{ width:240px; margin-bottom:10px;}
#box div img{ display:block;border:1px solid #ddd; width:220px; margin:0 8px;}
</style>
</head>
<body>
    <!--瀑布流-->
    <div id="box">
     <div><img src="images/1.png"></div>
        <div><img src="images/2.png"></div>
        <div><img src="images/3.png"></div>
        <div><img src="images/4.png"></div>
        <div><img src="images/5.png"></div>
        <div><img src="images/9.png"></div>
        <div><img src="images/10.png"></div>
        <div><img src="images/3.png"></div>
        <div><img src="images/4.png"></div>
        <div><img src="images/5.png"></div>
        <div><img src="images/6.png"></div>
        <div><img src="images/7.png"></div>
        <div><img src="images/8.png"></div>
        <div><img src="images/9.png"></div>
        <div><img src="images/10.png"></div>
        <div><img src="images/3.png"></div>
        <div><img src="images/4.png"></div>
        <div><img src="images/5.png"></div>
        <div><img src="images/6.png"></div>
        <div><img src="images/7.png"></div>
    </div>
    
</body>
<script type="text/javascript">
window.onload=function(){
 //瀑布流
 var box=document.getElementById("box"); 
 function append(json){  
  var len=json.length;//获取个数
  
  for(var i=0;i<len;i++){
   //插入处理
   var obj=document.createElement("div");
   var oimg=document.createElement("img");
   oimg.src=json[i].url; //赋值路径 
   obj.appendChild(oimg);
   box.appendChild(obj);
  };     
 };
 //滚动到最低部判断程序 
 window.onscroll=function(){
  var page_real_h=document.documentElement.scrollHeight;//页面真实高
  var page_see_h=document.documentElement.clientHeight;//页面可见高
  var bot=page_real_h-page_see_h;//到最底部值
  var xtop=document.documentElement.scrollTop||document.body.scrollTop;////获取时时滚动值,兼容谷歌
  if(xtop==bot){//到最底部
   setTimeout(function(){
    //ajax请求哪来的数据
    var json_ajax=[    
     {url:"images/4.png",w:185,h:116},
     {url:"images/12.png",w:150,h:100},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
     {url:"images/6.png",w:148,h:114},
     {url:"images/5.png",w:188,h:107},
     {url:"images/2.png",w:98,h:108},
     {url:"images/3.png",w:106,h:145},
     {url:"images/1.png",w:70,h:120},
     {url:"images/4.png",w:185,h:116},
     {url:"images/11.png",w:150,h:187},
     {url:"images/10.png",w:148,h:132},
     {url:"images/9.png",w:152,h:110},
     {url:"images/8.png",w:109,h:123},
     {url:"images/7.png",w:95,h:142},
    ];
    append(json_ajax);//插入16个图片
   },800);
  }else{};
 };
 
 
};
</script>
</html>

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!