最终实例下载地址: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>
来源:oschina
链接:https://my.oschina.net/u/2352644/blog/649422