JavaScript—瀑布流的实现

130 阅读2分钟

什么是瀑布流

1.所有的盒子等宽不等高。
2.触底加载

思路

1.所有盒子设置定位,通过left和top值来灵活控制盒子的位置。
2.计算整个页面可以显示的列数(页面的宽/盒子的宽);
3.设置一下container的宽;
4.循环所有小盒子,将盒子放在对应的位置上(设置他们的left和top值);
4.1 准备一个数组,将每一列的高度放在数组中;
4.2 从第二列开始,每一张图片需要找到最小列,添加;
4.3 判断 盒子的高+距离顶部的高 小于 卷去的高+页面的高 需要加载新的数据。

CSS部分

.container{
	position: relative;	
	width: 1200px;
	margin: 20px auto;
}
.container .box{
	display: flex;
	width: 220px;
	margin: 20px 0 30px ;
	padding: 5px 0 0 15px;
	overflow: hidden;		
	position: absolute;
}
.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部分

	<div id="container" class="container">
		<div class="box">
			<div class="active">
				<img src="img/1.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/2.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/3.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/4.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/5.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/6.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/7.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/8.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/9.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/10.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/11.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/12.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/13.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/14.webp" />
			</div>
		</div>
		<div class="box">
			<div class="active">
				<img src="img/15.webp" />
			</div>
		</div>
	</div>

js部分

	window.onload = function () {
			const container = document.getElementById("container")
			const boxs = document.querySelectorAll("#container .box");
			//2.计算整个页面可以显示的列数
			let docWidth = document.documentElement.offsetWidth || document.body.offsetWidth;
			//盒子的宽
			const boxWidth = document.querySelector("#container .box").offsetWidth;
			//列数 向下取整
			let cols = Math.floor(docWidth / boxWidth);
			//3.设置一下container的宽  列数*盒子的宽
			container.style.width = cols * boxWidth + "px";
			// 4.循环所有小盒子,将盒子放在对应的位置上(设置他们的left和top值)
			// 4.1 准备一个数组,将每一列的高度放在数组中。
			let arr = [];
			for (let i = 0; i < boxs.length; i++) {
				//第一行 索引小于列数在第一行
				if (i < cols) {
					arr.push(boxs[i].offsetHeight);
					boxs[i].style.top = "0px"
					boxs[i].style.left = i * boxWidth + "px";
				} else {
					//数组中找到最小值
					let minHeight = Math.min(...arr);
					//修改top值
					boxs[i].style.top = minHeight + "px";
					//获取添加列的索引
					let index = arr.findIndex(item => {
						return item == minHeight;
					})
					// 修改left值  索引*盒子的宽
					boxs[i].style.left = index * boxWidth + "px";
					//修改数组中的最小值
					arr[index] += boxs[i].offsetHeight;
				}
			}
			//定义图片的路径数组
			const imgArr = ["img/1.webp", "img/2.webp", "img/3.webp", "img/4.webp", "img/5.webp", "img/6.webp", "img/7.webp",
				"img/8.webp", "img/9.webp", "img/10.webp", "img/11.webp", "img/12.webp", , "img/13.webp", "img/14.webp",
				"img/15.webp"
			]



			//页面滚动时,判断是不是要继续加载图片。
			function check() {
				//获取滚动条卷去的高度 + 视口的高度(兼容写法)
				let totalHeight = document.documentElement.scrollTop + document.documentElement.clientHeight || document.body
					.scrollTop + document.body.clientHeight
				//获取最小的高度
				let minHeight = Math.min(...arr);
				console.log(minHeight, totalHeight);
				if (minHeight < totalHeight) {
					//说明要继续加载数据
					for (let i = 0; i < imgArr.length; i++) {
						let div = document.createElement("div");
						div.classList.add("box");
						div.innerHTML = `<div class="active">
										<img src="${imgArr[i]}" />
									</div>`
						container.appendChild(div);
						//数组中找到最小值
						let minHeight = Math.min(...arr);
						//修改top值
						div.style.top = minHeight + "px";
						//获取添加列的索引
						let index = arr.findIndex(item => {
							return item == minHeight;
						})
						// 修改left值  索引*盒子的宽
						div.style.left = index * boxWidth + "px";
						//修改数组中的最小值
						arr[index] += div.offsetHeight;

					}
				}
			}

			//页面首页图片加载完后,判断一下需不需要再加载。
			check();
			window.onscroll = check;
		}
	</script>