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

Posted 鸣蜩铃兰香

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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”函数里面的代码实现了页面缩小图片的列数也会相应的改变哦~

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

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

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

以上是关于HTML+CSS+JS 瀑布流式布局(实现懒加载)的主要内容,如果未能解决你的问题,请参考以下文章

瀑布流式布局

css瀑布流间距不对

css 瀑布流布局问题 高手进

JS实现动态瀑布流及放大切换图片效果(js案例)

微信小程序下瀑布流加载解决方案

微信小程序下瀑布流加载解决方案