1.瀑布流布局简介
瀑布流布局简介:随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部,数据块就好像瀑布一样永远流不完。
瀑布流布局特点:图片等宽不等高
2.JavaScript原生方法实现瀑布流布局
index.html
<!DOCTYPE html>
<html>
<head>
<title>瀑布流布局</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="js/waterfall.js"></script>
</head>
<body>
<div id="main">
<div class="box">
<div class="pic">
<img src="images/1.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/2.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/3.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/4.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/5.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/6.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/7.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/8.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/9.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/10.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/11.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/12.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/13.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/14.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/15.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/16.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/17.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/18.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/19.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/20.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/21.jpg">
</div>
</div>
<div class="box">
<div class="pic">
<img src="images/22.jpg">
</div>
</div>
</div>
</body>
</html>
style.css
#main {
-webkit-column-width:202px;
-moz-column-width:202px;/*火狐*/
-o-column-width:202px;
-ms-column-width:202px;/*IE*/
/*
-webkit-column-count:5;
-moz-column-count:5;
-o-column-count:5;
-ms-column-count:5;
*/
-webkit-column-rule:2px dashed #f00;
-moz-column-rule:2px dashed #f00;
-o-column-rule:2px dashed #f00;
-ms-column-rule:2px dashed #f00;
/*-ms-column-gap*/
}
.box {
padding: 10px 0 0 15px;
/*float: left;图片可以显示在同一行中*/
}
.pic {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 5px #ccc;
width: 165px;
}
.pic img {
display: block;
width: 165px;
height: auto;
}
waterfall.js
window.onload = function () {//页面加载的时候执行脚本
waterfall('main','box');//操作main下的box
//模拟后台传给前端渲染的数据
var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};
window.onscroll = function() {//事件
//根据最后一张图片的位置
if(checkScrollSide()) {
var oParent = document.getElementById('main');
//将数据块渲染到页面的尾部
for(var i=0; i<dataInt.data.length; i++) {
var oBox = document.createElement('div');
oBox.className = 'box';
oParent.appendChild(oBox);
var oPic = document.createElement('div');
oPic.className = 'pic';
oBox.appendChild(oPic);
var oImg = document.createElement('img');
oImg.src = "images/" + dataInt.data[i].src;
oPic.appendChild(oImg);
}
waterfall('main','box');//将图片放在相应的位置上
}
}
}
function waterfall(parent, box) {
//将main下的所有class为box的元素取出来
var oParent = document.getElementById(parent);
//var oBoxs = document.getElementsByClassName("box");//IE8以下不兼容
var oBoxs = getByClass(oParent,box);//getElementsByClassName
//console.log(oBoxs.length);
//计算整个页面显示的列数(页面宽/box的宽),缩放窗口列数会发生变化
var oBoxW = oBoxs[0].offsetWidth;
//console.log(oBoxW);//202=图片宽165+内边距10*2+边框宽1*2+15
var cols = Math.floor(document.documentElement.clientWidth/oBoxW);
//console.log(cols);
//设置main的宽度,否则列数还是不固定
oParent.style.cssText = 'width:'+oBoxW*cols+'px;margin:0 auto;';//0 表示上下边界为0,左右根据宽度自适应相同值(即居中)
var hArr = [];//存放每一列高度的数组
for (var i = 0; i < oBoxs.length; i++) {
if(i<cols) {//cols列数
hArr.push(oBoxs[i].offsetHeight);
} else {
var minH = Math.min.apply(null, hArr);//获得hArr中最小的数值
var index = getMinhIndex(hArr,minH);
oBoxs[i].style.position = 'absolute';
oBoxs[i].style.top = minH + 'px';
//oBoxs[i].style.left = oBoxW*index + 'px';
oBoxs[i].style.left = oBoxs[index].offsetLeft + 'px';//另外一种写法
hArr[index] += oBoxs[i].offsetHeight;//否则图片会重叠
}
}
//console.log(hArr);
//console.log(minH);
}
//根据class获取元素
function getByClass(parent,clsName) {
var boxArr = new Array();//用来存储获取到的所有class为box的元素
var oElements = parent.getElementsByTagName('*');
for(var i=0; i<oElements.length; i++) {
if(oElements[i].className == clsName) {
boxArr.push(oElements[i]);
}
}
return boxArr;
}
function getMinhIndex(arr,val) {
for(var i in arr) {
if(arr[i] == val) {
return i;
}
}
}
//检测是否具备了滚动条加载数据块的条件
function checkScrollSide() {
var oParent = document.getElementById('main');
var oBoxs = getByClass(oParent,'box');
var lastBoxH = oBoxs[oBoxs.length-1].offsetTop + Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);//红线的长度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//滚动条滑动的距离(标准模式与混杂模式)
//console.log(scrollTop);
var documentH = document.documentElement.clientHeight || document.body.clientHeight;//页面高度(标准模式与混杂模式)
//console.log(documentH);
return (lastBoxH < scrollTop + documentH)?true:false;
}
2.JQuery实现瀑布流布局
index.html中head标签中引入:
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
style.css文件和JavaScript方式实现瀑布流布局的代码相同。
waterfall.js
$(window).on('load',function() {
waterfall();
var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};
$(window).on('scroll', function(){
if(checkScrollSlide()) {
$.each(dataInt.data,function(key,value){
console.log("key="+key);
console.log("value="+value);
var oBox = $('<div>').addClass('box').appendTo('#main');
var oPic = $('<div>').addClass('pic').appendTo($(oBox));
var oImg = $('<img>').attr('src','images/'+$(value).attr('src')).appendTo($(oPic));
})
waterfall();
}
})
})
function waterfall() {
var $boxs = $('#main>div');//匹配一级div(包含选择器)
var w = $boxs.eq(0).outerWidth();//包括padding,border的宽度
var cols = Math.floor($(window).width()/w);
$('#main').width(w*cols).css('margin','0 auto');//居中显示
var hArr = [];
$boxs.each(function(index, value) {
var h = $boxs.eq(index).outerHeight();//包括padding,border
if(index < cols) {
hArr[index] = h;
} else {
var minH = Math.min.apply(null,hArr);
var minHIndex = $.inArray(minH, hArr);
$(value).css({
'position' : 'absolute',
'top' : minH + 'px',
'left' : minHIndex*w + 'px'
})
hArr[minHIndex] += h;
}
})
}
function checkScrollSlide() {
var $lastBox = $('#main>div').last();//获取最后一个box
var lastBoxDis = $lastBox.offset().top + Math.floor($lastBox.outerHeight()/2);
var scrollTop = $(window).scrollTop();
var documentH = $(window).height();
return (lastBoxDis<scrollTop+documentH)?true:false;
}
3.CSS3多栏布局实现瀑布流布局
index.html文件内容和JavaScript原生方法实现瀑布流布局代码相同。
style.css
#main {
-webkit-column-width:202px;
-moz-column-width:202px;/*火狐*/
-o-column-width:202px;
-ms-column-width:202px;/*IE*/
/*
-webkit-column-count:5;
-moz-column-count:5;
-o-column-count:5;
-ms-column-count:5;
*/
-webkit-column-rule:2px dashed #f00;
-moz-column-rule:2px dashed #f00;
-o-column-rule:2px dashed #f00;
-ms-column-rule:2px dashed #f00;
/*-ms-column-gap*/
}
.box {
padding: 10px 0 0 15px;
/*float: left;图片可以显示在同一行中*/
}
.pic {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 5px #ccc;
width: 165px;
}
.pic img {
display: block;
width: 165px;
height: auto;
}
4.三种实现方式比较
1.JavaScript原生方式
1)需要计算列数,列数=浏览器窗口宽度/图片宽度
2)图片显示是按照计算的位置横向显示,位置确定,比较规范
2.CSS3方式
1)设置列宽后,浏览器自动计算显示的列数,性能高
2)列宽随浏览器窗口大小进行改变,用户体验差
3)图片按照垂直顺序排列,打乱了图片的显示顺序
4)兼容性:IE10+才支持此属性,如果想要所有浏览器实现瀑布流布局,还是需要使用JS实现。
本文使用到的图片下载地址:http://download.csdn.net/detail/u013940159/9644611
ps:作者第一次写关于前端方面的博客,有不对的地方还望大家指出来,谢谢