<div id="main">
<div class="box">
<div class="pic">
<img src="images/0.png">
</div>
</div>
<div class="box">
<div class="pic">
<img style="height: 200px" src="images/1.png">
</div>
</div>
</div>
*{margin: 0;padding: 0;}
#main{
position: relative;
margin: 0 auto;
}
.box{
padding: 15px 0 0 15px;
float: left;
}
.pic{
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 5px #cccccc;
padding: 10px;
}
.pic img{
width: 165px;
height: auto;
}
//封装class取元素的方法
function getByClass(parent,clsname){
var boxarray=new Array(),//用来存储获取到的所有class为box的元素
elements=parent.getElementsByTagName("*");
for(var i=0;i<elements.length;i++){
if(elements[i].className==clsname){
boxarray.push(elements[i]);
}
}
return boxarray;
}
获取第一行每个块的高度(offsetHeight),将第5个块放置到第一行块中高度最小的一个下面;
top为高度最小的那个块的高度,left为高度最小的块的left值(这里需知道高度最小的块在列数组中的索引);
依次类推,修改每次添加一个块的那个列的高度(原来高度加上增加块的高度)并重新找到高度最小的列,将下一个块补上去;
注意:第一行需不等高,若存在等高需处理等高问题;
function waterfall(parent,cls){
//将main下所有class的box的元素取出来
var parents=document.getElementById(parent);
var boxs=getByClass(parents,cls);
//计算整个页面显示的列数(页面宽度/box宽)
var bow_w=boxs[0].offsetWidth;//获取box的宽度
var cols=Math.floor(document.documentElement.clientWidth/bow_w);//页面宽度clientWidth
//设置main的宽度并居中显示
parents.style.cssText='width:'+(cols*bow_w)+'px; margin:0 auto';
var hArr=[];//用来存储高度的数组
for(var i=0;i<boxs.length;i++){
if(i<cols){//第一行
hArr.push(boxs[i].offsetHeight);
}else{
var minH=Math.min.apply(null,hArr);//求数组中高度最低的一列
var index=minindex(hArr,minH);//获取索引
//console.log(minH);
//boxs[i].style.cssText='position:absolute;top:'+minH+'px;left:'+bow_w*index+'px';
boxs[i].style.position='absolute';
boxs[i].style.top=minH+'px';
boxs[i].style.left=bow_w*index+'px';
//boxs[i].style.left=boxs[index].offsetLeft+'px';
hArr[index]+=boxs[i].offsetHeight;//修改列的高度
}
}
}
//封装求数组最小的索引的函数
function minindex(arr,val) {
for(var i in arr){
if(arr[i]==val){
return i;
}
}
}
5.滚动条下滑加载问题
当最后一个块滚动到露出一半高度时加载数据块,即当(块高度/2+块距离
)小于(窗口可视区域的高度+滚动条距离)就加载数据块;
加载数据块,动态创建dom元素,包裹加载数据图片,并调用瀑布流样式函数重新排列样式;
//封装检测是否具备滚动条加载数据块条件
function addbox(){
var parent=document.getElementById("main");
var boxs=getByClass(parent,'box');
var lastBoxH=boxs[boxs.length-1].offsetTop+Math.floor(boxs[boxs.length-1].offsetHeight/2);
var srcollTop=document.documentElement.scrollTop||document.body.scrollTop;
var screenheight=document.documentElement.clientHeight||document.body.clientHeight;
return (lastBoxH<srcollTop+screenheight)?true:false;
}
主代码:
window.onload=function(){
waterfall('main','box');
//加载json数据
var dataInt={
"data":[
{"src":"7.png"},
{"src":"1.png"},
{"src":"11.jpg"}
]
};
//滚动条加载数据块
window.onscroll=function(){
var main=document.getElementById("main");
if(addbox){
for(var i=0;i<dataInt.data.length;i++){
var box=document.createElement("div");
box.className="box";
main.appendChild(box);
var pic=document.createElement("div");
pic.className="pic";
box.appendChild(pic);
var Img=document.createElement("img");
Img.src="images/"+dataInt.data[i].src;
pic.appendChild(Img);
}
waterfall('main','box');//重新调用瀑布流样式函数排列样式
}
}
};
三、jQuery方法实现瀑布流
Jquery优势:链式操作、隐式迭代
1.封装瀑布流排列样式方法
注意:jQuery中width()方法获取元素的宽,outerWidth()获取元素的宽包含padding和margin边框等宽度; height()和outerHeight()方法同理;
$.inArray(value,array) 获取value这个值在数组array中的索引
在each(index,value)遍历中value直接操作是dom元素,需通过$(value)转换为jquery元素进行操作;
function waterfall(){
//计算列
var boxs=$("#main>div");
var w=boxs.eq(0).outerWidth();
var cols=Math.floor($(window).width()/w);
//设置main的宽
$("#mian").width(w*cols).css('margin','0 auto');
//判断高度最小列 放置后一个数据块
var harry=[];
boxs.each(function(index,value){
var h=boxs.eq(index).outerHeight();//获取每个数据块的高度
if(index<cols){
harry[index]=h;
}else{
var minH=Math.min.apply(null,harry);
var minHindex=$.inArray(minH,harry);//获取索引
$(value).css({ //需要把value的dom对象转换为jQuery $(value)
'position':'absolute',
'top':minH+'px',
'left':minHindex*w+'px'
});
harry[minHindex]+=boxs.eq(index).outerHeight(); //改变列的高度
}
})
}
2.滚动条加载数据块事件:
遍历json数据对象:$.each(json,function(index,value){});
$(window).on('load',function(){
waterfall();
//加载json数据
var dataInt={
"data":[
{"src":"7.png"},
{"src":"1.png"},
{"src":"11.jpg"}
]
};
$(window).on('scroll',function(){
if(addbox){
$.each(dataInt.data,function(index,value){ //遍历json数据
var box=$('<div></div>').addClass('box').appendTo($('#main'));
var pic=$('<div>').addClass('pic').appendTo($(box));
//console.log($(value).attr('src')); value转化为jQuery对象
var oimg=$('<img>').attr('src','images/'+$(value).attr('src')).appendTo($(pic));
});
waterfall();
}
})
});
封装加载数据块条件的方法:
Js中获取元素距离页面顶部的距离为offsetTop(),jquery中为.offset().top;
Js中获取自身高度为offsetHeight(),jquery使用outerHeight();
function addbox(){
var lastbox=$("#main>div").last();//获取最后一个数据块
var lastboxdis=lastbox.offset().top+Math.floor(lastbox.outerHeight()/2);//获取块距离+自身高度一半
var scrolltop=$(window).scrollTop();//获取滚动条高度
var documentH=$(window).height();//获取页面可视区高度
return (lastboxdis<scrolltop+documentH)?true:false;
}
一、css3方法实现瀑布流--多栏布局实现
语法:column-count 指定元素应分为的列数
column-width 指定元素的列的宽度
column-rule 指定所有列之间的规则(宽度,样式,颜色)
column-gap 指定列之间的差距
注意:IE10和opera支持多列属性;
兼容性 -moz- Firefox; -webkit- safari和chrome;
-o- opera; -ms- ;
#main{
column-width: 202px;
-moz-column-width: 202px;
-webkit-column-width: 202px;
/*column-count: 5;
-moz-column-count: 5;
-webkit-column-count: 5;*/
column-rule: 1px dashed silver;
-moz-column-rule:1px dashed silver;
-webkit-column-rule: 1px dashed silver;
column-gap: 10px;
-moz-column-gap: 10px;
-webkit-column-gap: 10px;
width: 1200px;
margin: 10px auto;
}