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”函数里面的代码实现了页面缩小图片的列数也会相应的改变哦~
这样我们一个基本的瀑布流式布局就完成辣~ !
但是把页面重新恢复之后会挤在一起,这个问题触及到了我的知识盲区,所以如果有懂的小伙伴可以一起交流哦。
(码字不易,能帮到看这篇文章的你就是我前进的动力,嘿咻
( •̀ ω •́ )✧)
本文地址:https://blog.csdn.net/qq_44386537/article/details/111772736
上一篇: Mysql学习(四) -- 相关知识