欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JS实现的瀑布流

程序员文章站 2022-06-01 23:29:46
...


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>
JS实现的瀑布流


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.onload=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.onscroll=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.onload=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.onscroll=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>