JS瀑布流

今天突然想起在极客学院看到过一个视频学习, 是关于JS瀑布流的教程。于是在闲暇之余,便点进去看了,结果只能看完第一个教程,剩下两个需要付费。好奇的心已经被勾起,所以不肯罢休的我只能找度娘了。

于是找到了一位coder的代码,学习了一下,然后自己再跟着思路自己搞了一个出来。

这是那位coder的文章地址:http://www.cnblogs.com/slowsoul/archive/2013/02/10/2909746.html

前台页面:

<body>
	<div id="container"> <!-- 图片最外层DIV -->
		<div class="box"> 
			<div class="box_img">   <!-- 包裹着图片的DIV -->
				<img src="images/1.jpg" alt="" />
			</div>
		</div>
		<div class="box">
			<div class="box_img">
				<img src="images/2.jpg" alt="" />
			</div>
		</div>
		<div class="box">
			<div class="box_img">
				<img src="images/3.jpg" alt="" />
			</div>
		</div>
	</div>
</body>

CSS:

#container
{
	position:relative;
}

.box{
	padding:5px;
	float:left; /*让图片浮动*/
}

.box_img{
	padding:5px;
	border:1px solid #ccc;
	box-shadow: 0 0 5px #ccc;
	border-radius:5px;
	position: relative;;
}

.box_img img{
	width:150px;    /*设定图片宽度为150px,高度则让其自动适应 */
	height:auto;
}
JS:

重要的部份来了,在学习过程当中,我在看完极客学院的第一个视频后,并没有得到思路,视频只是介绍了设置图片的样式和获取图片的过程,然后在找到其他coder的代码,仔细读过之后,才知道,重要的过程是:

(1)在重新排列图片的时候,第一行图片,正常摆放。从第二行开始,需要统计当前每一列已摆放的高度,然后算出当前累计高计最小的那一列,将下一张待排列的图片放到该列上。

2)如图所示,那么比如第一列当前累计高度最小,那么下一张等排列的图片A就会被放到第一列上去。变成下面这样:

(3)如此循环,直至把所有的图片都摆放完就OK了。

(4)那么问题来了,如果当窗口大小发生变化时,又如何处理?答案是再重复(1)~(3)的过程就行了,只不过需要重新计算一行当中可以摆放多少张图片。

代码如下:


window.onload = function(){
	imgLocation('container','box');  /* 加载时进行调用 */
}

window.onresize = function(){
	imgLocation('container','box'); /* 当窗口大小发生变化时需要重新排列图片 */
}

/*************************************
summary:排列图片
input:
	parent - 图片容器
	content - 获取的子元素ID
**************************************/
function imgLocation(parent,content){
	
	var cparent = document.getElementById(parent);
	var ccontent = getChildElement( cparent, content );   //将parent下的多个content全部取出
	
	var imgWidth = ccontent[0].offsetWidth;   //元素宽度,即图片的指定宽度
	
	var colsNum = Math.floor( document.documentElement.clientWidth / imgWidth ); //一行能放的个数 = 文档宽度 / 单个图片宽度
	
	cparent.style.cssText = "width:" + (imgWidth)*colsNum + "px; margin: 0 auto;";  //设置容器样式和宽度,使图片容器能够跟随窗口大小变化排列

	setColumnAllHeight(ccontent, colsNum); //进行计算和设置
}

/***********************************************
summary:获取parent下指定的content子元素
input:
	parent - 父对象
	content - 指定的className字符串

output:
	返回parent下的所有指定content子元素数组
************************************************/	
function getChildElement(parent,content){

	var contentArr = [];
	var allContent = parent.getElementsByTagName('*'); //获取所有子元素
	for( var i=0; i<allContent.length; i++){

		if( allContent[i].className == content ){ //进行筛选

			contentArr.push(allContent[i]);
		}
	}
	return contentArr;
}

/*****************************************
summary:获取每列中所有图片相加的高度
input:
	elementArr - 元素数组
	rowSize - 一行放置的元素个数
output: 返回计算出每列图片总高度的数组
*****************************************/
function setColumnAllHeight(elementArr,rowSize){

	clearStyle(elementArr); //清除样式,这个可能是我的样式问题

	var colTotal = []; //用于统计累计高度的数组
	
	for( var i=0; i<elementArr.length && i< rowSize; i++ ) //初始化,因为每行只能放rowSize个,先把第一个的高度进行初始化数组
	{
		colTotal[i] = elementArr[i].offsetHeight;
	}

	for( var i=rowSize; i<elementArr.length; i++ ){
		
		var minHIndex = getMinHeightIndex(colTotal); //获取当前在累计高度数组中最小值的索引

		elementArr[i].style.position = 'absolute'; //将其摆放到该列上
		elementArr[i].style.top = colTotal[minHIndex] + 'px'; //图片的top值就等于累计高度数组中最小值
		elementArr[i].style.left = elementArr[minHIndex].offsetLeft + 'px'; //距离网页左边的距离等于该列的左边距离

		colTotal[minHIndex] += elementArr[i].offsetHeight; //然后更新累计高度数组
	}
}

/*************************
summary:清除样式
*************************/
function clearStyle( arr ){

	for( var i=0; i<arr.length; i++ ){
		arr[i].style.cssText = '';
	}
}

/*******************************
summary:获取数组中最小值的索引
input:
	arr - 数组
*******************************/
function getMinHeightIndex( arr ){

	var index = -1;
	var minH = Number.MAX_VALUE;
	for( var i in arr ){

		if( arr[i] < minH ){

			minH = arr[i];
			var index = i;
		}
	}
	return index;
}

 完成后,运行截图如下:



总结:

其实瀑布流也没有想象中那么难,很多好的设计都是人想出来的,只要有想法,敢于实践,必定成功!我的这个demo多多少少还是有一些小问题,后面可以改进下,希望对大家有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值