瀑布流布局

1.瀑布流布局简介

瀑布流布局简介:随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部,数据块就好像瀑布一样永远流不完。
瀑布流布局特点:图片等宽不等高
瀑布流布局参考网址:

http://www.vip.com/

http://www.mogujie.com/


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:作者第一次写关于前端方面的博客,有不对的地方还望大家指出来,谢谢

相关文章
相关标签/搜索