最近公司的作品展示页面需要用瀑布流效果实现,整理了一下,瀑布流大致有两个问题,第一个是图片的排列问题,在这里我用设置一个数组,数组大小为浏览器容纳图片的个数,数组内容为图片的那一列的总高度,获取数组的最小值,在添加图片时以绝对定位的方式,改变数组的值。第二个是无限加载的问题,我用ajax封装了一些图片数据,每次滚动到距底部一段距离时加载ajax,达到这种无限的效果,剩下就是一些小细节了,比如改变浏览器大小时做适配等。具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#main {
position: relative;
}
.pin {
padding: 15px 0 0 15px;
float: left;
}
.content {
padding: 10px;
border: 1px solid #ccc;
content-shadow: 0 0 6px #ccc;
border-radius: 5px;
}
.content img {
width: 162px;
height: auto;
}
</style>
<script>
window.onload = function () {
waterfall('main', 'pin');
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 oPin = document.createElement('div'); //添加 元素节点
oPin.className = 'pin'; //添加 类名 name属性
oParent.appendChild(oPin); //添加 子节点
var ocontent = document.createElement('div');
ocontent.className = 'content';
oPin.appendChild(ocontent);
var oImg = document.createElement('img');
oImg.src = './images/' + dataInt.data[i].src;
ocontent.appendChild(oImg);
}
waterfall('main', 'pin');
}
;
}
}
function waterfall(parent, pin) {
var oParent = document.getElementById(parent);// 父级对象
var aPin = getClassObj(oParent, pin);// 获取存储块框pin的数组aPin
var iPinW = aPin[0].offsetWidth;// 一个块框pin的宽
var num = Math.floor(document.documentElement.clientWidth / iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
oParent.style.cssText = 'width:' + iPinW * num + 'px;margin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
var pinHArr = [];//用于存储 每列中的所有块框相加的高度。a
for (var i = 0; i < aPin.length; i++) {//遍历数组aPin的每个块框元素
var pinH = aPin[i].offsetHeight;
if (i < num) {
pinHArr[i] = pinH; //第一行中的num个块框pin 先添加进数组pinHArr
} else {
var minH = Math.min.apply(null, pinHArr);//数组pinHArr中的最小值minH
var minHIndex = getminHIndex(pinHArr, minH);
aPin[i].style.position = 'absolute';//设置绝对位移
aPin[i].style.top = minH + 'px';
aPin[i].style.left = aPin[minHIndex].offsetLeft + 'px';
//数组 最小高元素的高 + 添加上的aPin[i]块框高
pinHArr[minHIndex] += aPin[i].offsetHeight;//更新添加了块框后的列高
}
}
}
/*
*通过父级和子元素的class类 获取该同类子元素的数组
*/
function getClassObj(parent, className) {
var obj = parent.getElementsByTagName('*');//获取 父级的所有子集
var pinS = [];//创建一个数组 用于收集子元素
for (var i = 0; i < obj.length; i++) {//遍历子元素、判断类别、压入数组
if (obj[i].className == className) {
pinS.push(obj[i]);
}
}
;
return pinS;
}
/****
*获取 pin高度 最小值的索引index
*/
function getminHIndex(arr, minH) {
for (var i in arr) {
if (arr[i] == minH) {
return i;
}
}
}
function checkscrollside() {
var oParent = document.getElementById('main');
var aPin = getClassObj(oParent, 'pin');
var lastPinH = aPin[aPin.length - 1].offsetTop + Math.floor(aPin[aPin.length - 1].offsetHeight / 2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//注意解决兼容性
var documentH = document.documentElement.clientHeight;//页面高度
return (lastPinH < scrollTop + documentH) ? true : false;//到达指定高度后 返回true,触发waterfall()函数
}
</script>
</head>
<body>
<div id="main">
<div class="pin">
<div class="content">
<img src="images/1.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/2.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/3.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/4.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/5.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/6.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/7.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/8.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/9.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/10.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/11.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/12.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/13.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/14.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/15.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/16.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/17.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/18.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/19.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/20.jpg"/>
</div>
</div>
<div class="pin">
<div class="content">
<img src="images/21.jpg"/>
</div>
</div>
</div>
</body>
</html>
当然以上的是用纯JavaScript实现的,我们可以用jQuery实现它,原理一样,代码如下:
html代码:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<link href="css/style.css" type="text/css" rel="stylesheet">
<script src="js/jquery-2.1.1.min.js">
</script>
<script src="js/myjs.js">
</script>
</head>
<body>
<div id="container">
<div class="box">
<div class="content">
<img src="image/1.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/2.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/3.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/4.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/5.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/6.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/7.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/8.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/9.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/10.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/11.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/1.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/2.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/3.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/4.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/5.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/6.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/7.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/8.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/9.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/10.jpg">
</div>
</div>
<div class="box">
<div class="content">
<img src="image/11.jpg">
</div>
</div>
</div>
</body>
</html>
$(document).ready(function(){
$(window).on("load",function(){
imgLocation();
$(window).resize(function () {
imgLocation();
})
var dataImg={"data":[{"src":"1.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"}]};
window.οnscrοll=function(){
if(scrollside()){
$.each(dataImg.data,function(index,value){
var box=$("<div>").addClass("box").appendTo($("#container"));
var content=$("<div>").addClass("content").appendTo(box);
$("<img>").attr("src","./image/"+$(value).attr("src")).appendTo(content);
});
}
imgLocation();
};
});
});
//让图片排列好
function imgLocation(){
var num=Math.floor($(window).width()/$(".box").eq(0).width());
var boxArr=[];
$(".box").each(function(index,value){
var boxHeight=$(".box").eq(index).height();
if(index<num){
boxArr[index]=boxHeight;
$(value).css({
"position":"absolute",
"left":index*$(value).width(),
"top":"0"
})
}else{
var minboxHeight=Math.min.apply(null,boxArr);//最小高度
var minbox= $.inArray(minboxHeight,boxArr);//在第几个位置
$(value).css({
"position":"absolute",
"top":minboxHeight,
"left":$(".box").eq(minbox).position().left
})
boxArr[minbox]=boxArr[minbox]+$(value).height();
}
});
}
function scrollside(){
var documentHeight=$(document).height();
var scrollHeight=$(document).scrollTop();
var winHight=$(window).height();
//alert(documentHeight+"--"+scrollHeight+"--"+winHight);
return (documentHeight-scrollHeight-winHight)<50?true:false;
}
OK,以上两种方式都能实现瀑布流效果,运行的效果如图: