最终实例下载地址:http://www.oschina.net/code/snippet_2352644_55042
一.基本瀑布流实现
这篇博客也是实例的讲解,本来已经完成了一半,因为临时有事出去,再回来一个没注意,关闭了页面,我记得明明会自动保存的,哎!
图片放在images目录下:
4.png
10.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>