HTML+CSS+JS 瀑布流式布局(实现懒加载)

HTML + JS+CSS实现瀑布流式布局(包含懒加载)

前几天兴致来了想做一个瀑布流布局的网页,然后就有了各种“神操作”,也在网上看了一些相关的知识点;所以这里对自己这几个小时来一个总结(附源码)

首先来说一下瀑布流的原理吧:瀑布流是许多数据块组成的,可以是图片,可以是div,但是它们都有一个特点,就是等宽不等高,正是因为它等宽不等高,所以如果按部就班的排布的话,才会出现很大的缝隙,特别不好看,说白了瀑布流布局就是充分利用图片之间的空隙来合理的布局,使布局看起来好看。

首先上CSS布局(因为个人喜欢比较美的事物,所以写的比较多……嘿)

*{
	margin: 0 ;
	padding: 0;
	background-color: #333;
}
.container{
	position: relative;	
	width: 1200px;
	margin: 20px auto;
}
.container .box{
	display: flex;
	width: 178px;
	margin: 20px 0 30px ;
	padding: 5px 0 0 15px;
	float: left;
	overflow: hidden;		
}
.container .box .active{
	padding: 10px;
	border: 1px solid #cccccc;
	box-shadow: 0 0 5px #ccc;
	border-radius: 5px;
}
.container .box img{
	max-width: 100%;
}
.container .box h2{
	margin: 10px 0 0;
	padding: 0;
	font-size: 20px;
	color: white;
}
.container .box p{
	margin: 0;
	padding: 0 0 10px;
	font-size: 16px;
	color: floralwhite;
}

这里把HTML代码也附上(这里我是把CSS和JS分开写了)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<link href="css/falls.css" rel="stylesheet" />
	<script src="js/falls.js"></script>
	<body>
		<div id="container" class="container">
			<div class="box">
				<div class="active">
					<img src="img/1.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/2.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/3.jpg" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/4.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/5.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/6.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/7.jpg" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
			<div class="box">
				<div class="active">
					<img src="img/8.png" />
					<h2>this is title</h2>
					<p>You just need to know what to look.</p>
				</div>
			</div>
		</div>
	</body>
</html>

没有加入JS就是这副模样
在这里插入图片描述
在明白了瀑布流的原理之后现在我们来实现瀑布流及自动加载;首先我们需要平铺第一行,这里我们铺了六张图片,然后就该铺第二行了,那这个待插入的图片应该放在哪个位置呢,我们可以得到每一列的高度,也就是每一列的数据块的高度加起来,得到六个高度的数值,我们算出哪一列高度最小就把待插入的图片插入到那一列的正下方,利用绝对定位定位过去(因为是绝对定位,所以top是距离页面顶部高度),left就是第几列乘以数据块宽度就可以了,如下图,待插入图片应该插入到这里
瀑布流式布局效果展示铺垫了这么多,重点来了!上JS

		window.onload=function(){
			//开始即调用
			waterfall('container','box')
			
			var dataInt = {
				"data": [
					{"src": '1.png'},{"src": '2.png'}, 
					{"src": '3.jpg'},{"src": '4.png'},
					{"src": '5.png'},{"src": '6.png'},
					{"src": '7.jpg'},{"src": '8.png'},
				]
			}
			
			//监听滚动条事件
			window.onscroll=function(){
				//检查是否具备了滚动条件
				if(checkScrollSlide){
					var ocontent = document.getElementById('container');
					//创建div,并将其加到所有box后面
					for(var i = 0; i < dataInt.data.length; i++) {
						var obox = document.createElement('div');
						obox.className = 'box';
						ocontent.appendChild(obox);
						var opic = document.createElement('div');
						opic.className = 'active';
						obox.appendChild(opic);
						var oimg = document.createElement('img');
						oimg.src = "img/" + dataInt.data[i].src;
						opic.appendChild(oimg);
						var oh=document.createElement('h2')
						oh.innerHTML='this is title'
						opic.appendChild(oh);
						var op=document.createElement('p')
						op.innerHTML='You just need to know what to look.'
						opic.appendChild(op)
					}
					waterfall('container', 'box');
				}
			}
		}
		
		function waterfall(content,box){
			//获取大盒子(container)里的所有小盒子(box)
			var ocontent=document.getElementById(content);
			var oboxs=getByClass(ocontent, box);
			//计算整个页面显示的列数(页面宽/box的宽);
			var oboxW = oboxs[0].offsetWidth;
			//Math.floor 向下取整
			var cols = Math.floor(document.documentElement.clientWidth / oboxW);
			//设置container的宽度(这里用刚刚计算出来的列数乘盒子的宽度(oboxW * cols)得到的)
			ocontent.style.cssText = 'width:' + oboxW * cols + 'px;margin:20 auto';
			var heightArr = [];
			for(var i = 0; i < oboxs.length; i++) {
				if(i < cols) {
					// 将前cols张图片的宽度记录到hArr数组中(第一行的高度)
					heightArr.push(oboxs[i].offsetHeight);
				} else {
					//从第二行开始就开始找最小的高度了,决定带插入图片该插入到哪里
					//js Math.min.apply()方法,取出数组中的最小值
					var minH = Math.min.apply(null, heightArr);
					var index = getMinhIndex(heightArr, minH);
					// 设置最小高度的图片的style为绝对定位,并设置top和left
					oboxs[i].style.position = 'absolute';
					oboxs[i].style.top = minH + 'px';
					oboxs[i].style.left = oboxs[index].offsetLeft+'px';
					heightArr[index] += oboxs[i].offsetHeight;
				}
			}
		}
		
		//返回所有的box盒子
		function getByClass(content, cName){
			var boxArr = new Array(),
				oElements = content.getElementsByTagName('*');
			for(var i = 0; i < oElements.length; i++) {
				if(oElements[i].className == cName) {
					boxArr.push(oElements[i]);
				}
			}
			return boxArr;
		}
		
		//获取数组中最小值的下标值
		function getMinhIndex(arr, val) {
			for(var i in arr) {
				if(arr[i] == val) {
					return i;
				}
			}
		}
		
		//定义函数检测是否具备了滚动加载数据块的条件
		function checkScrollSlide(){
			var ocontent = document.getElementById('container');
			var oboxs = getByClass(ocontent, 'box');
			//获取最后一个box到顶部的距离+ 它自身一半的距离
			var lastboxH = oboxs[oboxs.length - 1].offsetTop + Math.floor(oboxs[oboxs.length - 1].offsetHeight / 2);
			//获取滚动条滚动距离(为了消除标准模式和怪异模式之间的差别而做的兼容)
			var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
			// 获取window可视化的高度
			var height = document.body.clientHeight || document.documentElement.clientHeight;
			return(lastboxH < scrollTop + height) ? true : false;
		}

代码不复杂,多看几遍多敲几遍就能理解,这里主要讲解一下最后“function checkScrollSlide()”的思想;因为我们这个要实现一直滑一直滑的效果(也就是懒加载),所以我们这里就拿最后一张图片来做对比,通俗理解函数“checkScrollSlide()”的作用就是最后一张图片露出一半了你就应该加载。

然后之前的“waterfall”函数里面的代码实现了页面缩小图片的列数也会相应的改变哦~

这样我们一个基本的瀑布流式布局就完成辣~ !

但是把页面重新恢复之后会挤在一起,这个问题触及到了我的知识盲区,所以如果有懂的小伙伴可以一起交流哦。

(码字不易,能帮到看这篇文章的你就是我前进的动力,嘿咻
( •̀ ω •́ )✧)

猜你喜欢

转载自blog.csdn.net/qq_44386537/article/details/111772736