JS实现的瀑布流


js实现的瀑布流

1. HTML和CSS的布局

首先用HTML和CSS实现瀑布流的布局:如下图,为了让js可以获得盒子offsetleft等最好让盒子使用padding分开之间的距离,首先图片外面得有两层盒子,内层用来设置大盒子与图片之间的距离(给pic设置padding),外层用来设置每个图片大盒子之间的距离(给box设置padding-left和padding-top)。当然这两层盒子的大小是相同的,为了让盒子美观可以给pic设置一些CSS3的属性(box-shadow,border等)。 最后让所有的图片大盒子(box)都浮动起来,以保证,因为js加上的图要用到绝对定位所以还需要给容纳box的盒子main设置相对定位。

HTML

<body>
	<div id="main">
		<div class="box">
			<div class="pic">
				<img src="img/0.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/1.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/2.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/3.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/4.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/5.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/6.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/7.jpg" />
			</div>
		</div>
		<div class="box">
			<div class="pic">
				<img src="img/8.jpg" />
			</div>
		</div>
	</div>
</body>

CSS

<style>
	*{margin: 0;padding: 0;}
	#main{
		margin: 0 auto;
		position: relative;
		padding-right: 15px;
		/*使main居中*/
	}
	.box{
		padding: 15px 0 0 15px;
		float: left;
	}
	.pic{
		padding: 10px;
		border: 1px solid black;
		box-shadow: 0 0 5px #000000;
	}
	.pic img{
		width: 100px;
		height: auto;
	}
</style>


2.JS设计

  1. 瀑布流函数
  • 找到所有的box盒子(比较类名)
  • 计算一行图片盒子box的数目:一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
  • 给main盒子设置宽度,设置了以后才可以使其居中:main的宽度 =box图片的数目*box图片的宽度
  • 创建一个新的数组,存储第一行box的高度
  • 保存最小高度(第一行图片高度最小值就是最小高度),并且找到它的索引号(用一个函数,比较第一行的高度值哪一个和最小高度值一样,一样则return索引号)
  • 给接下来的图片设置绝对定位使它在第一行高度最小的下面,并且增加设置后那一行的高度。
function waterfall(main,box){
					var main=document.getElementById(main);
					var all=main.getElementsByTagName("*");
					var boxArr=[];   //找到classname为box的盒子    存放box
					var width=0;
					for (var i=0;i<all.length;i++) {
						if(all[i].className==box){
							boxArr.push(all[i]);
						}
					}
					getWidth();//刚进入页面时计算图片box的数目
					function getWidth(){
						//计算一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
						boxNum=Math.floor(client().width/boxArr[0].offsetWidth);
						//设置main的宽度 =box图片的数目*box图片的宽度---->可以使main居中
						main.style.width=boxNum*boxArr[0].offsetWidth+"px";
						width=boxArr[0].offsetWidth;
					}
					//创建一个新的数组,存储第一行box的高度
					var boxHeight=[];
					for (var i=0;i<boxArr.length;i++) {
						if(i<boxNum){//当第一行时,存储第一行的高度
							boxHeight.push(boxArr[i].offsetHeight);
						}
						else{//apply改变函数/方法中this的指向
							var minH=Math.min.apply(null,boxHeight);   //保存最小高度
							//图片的高度就是最小高度
							var minIndex=getMinHIndex(boxHeight,minH);//找到最小高度的索引号
							boxArr[i].style.position = "absolute";
							boxArr[i].style.top=minH+"px";
							boxArr[i].style.left=boxArr[minIndex].offsetLeft+"px";
							boxHeight[minIndex]+=boxArr[i].offsetHeight;
						}
					}
					function getMinHIndex(arrll,minH){//找到最小高度的索引号
						for (var j=0;j<arrll.length;j++) {
							if(boxHeight[j]==minH)
							{
								return j;
							}
						}
					}
				}


2. 下拉事件

用一个数组存储接下来图片的路径,在下拉事件里面首先判断图片是否需要加载(当最下面一行图的一半出来时),需要返回true,不需要返回false。当需要加载时新创建box盒子插入到main里面并且设置类名,再创建pic盒子插入新建的box盒子里面,设置类名,再创建img插入到新建的pic盒子里面,并且给img添加图片大小,和图片宽度(所有图片等宽)最后进行瀑布流函数。

			window.οnlοad=function(){
				waterfall("main","box");//瀑布流函数
				//下拉事件
				var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'}]};
				window.οnscrοll=function(){
					if(check()){
						var main=document.getElementById("main");
						for(var i=0;i<dataInt.data.length;i++){
							var newBox = document.createElement("div");
							newBox.className="box";
							main.appendChild(newBox);
							var newPic = document.createElement("div");
							newPic.className="pic";
							newBox.appendChild(newPic);
							var newImg=document.createElement("img");
			                newImg.src='img/'+dataInt.data[i].src;
			                newImg.style.width=100+"px";
			                newImg.className='Img';
			                newPic.appendChild(newImg);
						}
						waterfall("main","box");//瀑布流函数
					}
				}
			}

3. 关于client和scroll的兼容
//检测scroll
				function scroll(){
					if(window.pageXOffset!=null){
						return{
							top: window.pageYOffset,
							left: window.pageXOffset
						}
					}
					else if(document.compatMode=="CSS1compat"){
						return{
							top: document.documentElement.scrollTop,
							left: document.documentElement.scrollLeft
						}
					}
					return{
						top: document.body.scrollTop,
						left: document.body.scrollLeft
					}
				}
			//检测屏幕宽度的函数
				function client(){
						if(window.innerWidth!=null){
							return{
								width: window.innerWidth,
								height: window.innerHeight
							}
						}
						else if(window.compatMode=="CSS1compat"){
							return{
								width: window.documentElement.width,
								height: window.documentElement.height
							}
						}
						else{
							return{
								width: window.body.width,
								height: window.body.height
							}
						}
				}

3. 瀑布流完成:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style>
			*{margin: 0;padding: 0;}
			#main{
				margin: 0 auto;
				position: relative;
				padding-right: 15px;
				/*使main居中*/
			}
			.box{
				padding: 15px 0 0 15px;
				float: left;
			}
			.pic{
				padding: 10px;
				border: 1px solid black;
				box-shadow: 0 0 5px #000000;
			}
			.pic img{
				width: 100px;
				height: auto;
			}
		</style>
		<script>			
			window.οnlοad=function(){
				waterfall("main","box");//瀑布流函数
				//下拉事件
				var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'}]};
				window.οnscrοll=function(){
					if(check()){
						var main=document.getElementById("main");
						for(var i=0;i<dataInt.data.length;i++){
							var newBox = document.createElement("div");
							newBox.className="box";
							main.appendChild(newBox);
							var newPic = document.createElement("div");
							newPic.className="pic";
							newBox.appendChild(newPic);
							var newImg=document.createElement("img");
			                newImg.src='img/'+dataInt.data[i].src;
			                newImg.style.width=100+"px";
			                newImg.className='Img';
			                newPic.appendChild(newImg);
						}
						waterfall("main","box");//瀑布流函数
					}
				}
			}
			//加载函数
			function check(){
				var main = document.getElementById("main");
				//取出所有的box
				var box = document.getElementsByClassName("box");
				var lastBoxH=box[box.length-1].offsetTop+Math.floor(box[box.length-1].offsetHeight/2);
				var scrollTop=scroll().top;
				var height=client().height;
				return (lastBoxH<scrollTop+height)?true:false;
			}
			//瀑布流函数
			function waterfall(main,box){
					var main=document.getElementById(main);
					var all=main.getElementsByTagName("*");
					var boxArr=[];   //找到classname为box的盒子    存放box
					var width=0;
					for (var i=0;i<all.length;i++) {
						if(all[i].className==box){
							boxArr.push(all[i]);
						}
					}
					getWidth();//刚进入页面时计算图片box的数目
					function getWidth(){
						//计算一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
						boxNum=Math.floor(client().width/boxArr[0].offsetWidth);
						//设置main的宽度 =box图片的数目*box图片的宽度---->可以使main居中
						main.style.width=boxNum*boxArr[0].offsetWidth+"px";
						width=boxArr[0].offsetWidth;
					}
					//创建一个新的数组,存储第一行box的高度
					var boxHeight=[];
					for (var i=0;i<boxArr.length;i++) {
						if(i<boxNum){//当第一行时,存储第一行的高度
							boxHeight.push(boxArr[i].offsetHeight);
						}
						else{//apply改变函数/方法中this的指向
							var minH=Math.min.apply(null,boxHeight);   //保存最小高度
							//图片的高度就是最小高度
							var minIndex=getMinHIndex(boxHeight,minH);//找到最小高度的索引号
							boxArr[i].style.position = "absolute";
							boxArr[i].style.top=minH+"px";
							boxArr[i].style.left=boxArr[minIndex].offsetLeft+"px";
							boxHeight[minIndex]+=boxArr[i].offsetHeight;
						}
					}
					function getMinHIndex(arrll,minH){//找到最小高度的索引号
						for (var j=0;j<arrll.length;j++) {
							if(boxHeight[j]==minH)
							{
								return j;
							}
						}
					}
				}
			
			
			//公用函数
			
			
			//检测scroll
				function scroll(){
					if(window.pageXOffset!=null){
						return{
							top: window.pageYOffset,
							left: window.pageXOffset
						}
					}
					else if(document.compatMode=="CSS1compat"){
						return{
							top: document.documentElement.scrollTop,
							left: document.documentElement.scrollLeft
						}
					}
					return{
						top: document.body.scrollTop,
						left: document.body.scrollLeft
					}
				}
			//检测屏幕宽度的函数
				function client(){
						if(window.innerWidth!=null){
							return{
								width: window.innerWidth,
								height: window.innerHeight
							}
						}
						else if(window.compatMode=="CSS1compat"){
							return{
								width: window.documentElement.width,
								height: window.documentElement.height
							}
						}
						else{
							return{
								width: window.body.width,
								height: window.body.height
							}
						}
				}
		</script>
	</head>
	<body>
		<div id="main">
			<div class="box">
				<div class="pic">
					<img src="img/0.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/1.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/2.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/3.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/4.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/5.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/6.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/7.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/8.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/9.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/10.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/11.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/12.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/13.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/14.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/15.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/16.jpg" />
				</div>
			</div>
			<div class="box">
				<div class="pic">
					<img src="img/17.jpg" />
				</div>
			</div>
		</div>
	</body>
</html>




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值