文章目录
一.CSS实现瀑布流
代码
<style>
/* 多列布局写瀑布流:*/
*{margin: 0;padding: 0;}
body{
background: url(images/a.png),#000 url(images/bg.gif);
}
.content{
column-count:10;
}
figure{
border: 2px solid white;
padding: 10px 0px;
color: white;
text-align: center;
break-inside: avoid;
}
figure img{
width: 100%;
}
figcaption{
font-size: 35px;
text-align: center;
}
</style>
<body>
<div class="content">
<!-- 快捷键:figure*50>img[src="images/$.png"] -->
<figure><img src="../images/1.jpg" alt=""><figcaption>往后余生,风雪是你</figcaption></figure>
...2~39略...
<figure><img src="../images/40.jpg" alt=""><figcaption>往后余生,风雪是你</figcaption></figure>
</div>>
</body>
二.JS实现瀑布流
主要思路:
若图片索引小于列数:
正常输出,
并用一个空数组记录第一行每张图片的高度
若图片索引大于列数:
先找出高度数组的最小值,并在最短图片的下方添加图片
更新其高度(此时新的最短图片出现了)
重复以上步骤
1.面向过程的瀑布流
代码:
<body>
<div id="box">
<!-- 快捷键:img[src="../images/$.jpg" width="220px"]*40 -->
<img width="220px" src="../images/1.jpg" alt="">
...
<img width="220px" src="../images/40.jpg" alt="">
</div>
</body>
<script>
/*需要图片加载完才能获取到其高度*/
window.onload = function() {
//1.获取节点
var imgs = document.querySelectorAll("img");
//2.获取当前页面与图片的宽度.并由此得出列数
/*图片宽度都是一样的*/
var clientW = document.body.clientWidth;
var imgW = imgs[0].offsetWidth;
var column = parseInt(clientW / imgW);
//3.设置左边距
var marL = 10;
//4.追加图片
//设置一个空数组接收首行图片高度
var arrH = [];
for (var i = 0; i < imgs.length; i++) {
//第一行:正常显示并记录每张图片的高
if (i < column) {
imgs[i].style.left = (imgW + marL) * i + 'px';
// imgs[i].style.top = 0 + 'px';
arrH.push(imgs[i].offsetHeight);
}
//非第一行:不断地在最短图片下方添加新图片并更新其高度
else {
//找出最小高度L先假设一个最小高度白让其不断与数组元素对比,
//若有前者大于后者的情况则让前者等于后者
var minH = arrH[0],
index = 0;
for (var j = 0; j < arrH.length; j++) {
if (minH > arrH[j]) {
minH = arrH[j];
index = j;
}
}
//在最短图片下方追加图片
imgs[i].style.left = imgs[index].offsetLeft + 'px';
imgs[i].style.top = minH + 'px';
//更新图片高度(实际上就是其所在列的总高度)
arrH[index] = minH + imgs[i].offsetHeight;
}
}
}
</script>
2.面向对象的瀑布流
代码:
<style>
* {
position: relative;
}
img {
display: block;
width: 220px;
}
#box {
margin: 0 auto;
}
.item {
box-shadow: 2px 2px 2px #999999;
position: absolute;
}
</style>
<body>
<div id="box">
<!-- <img src="../images/1.jpg" alt="" srcset=""> -->
</div>
</body>
<script>
// 瀑布流思路:css固定每张图宽度=>
// 加载第一行记录每张图片的高度=>在最短图片下方添加图片
class WaterFall {
constructor() {
// 节点
this.boxObj = document.getElementById("box");
this.imgsObj = document.querySelectorAll("img");
this.appendImg(); //创建和追加节点
// 列数
this.cliW = document.body.clientWidth;
// this.imgW = imgsObj[0].offsetWidth;
this.imgW = 220;
this.columns = parseInt(this.cliW / this.imgW);
// 间隙
this.leftM = 10;
this.topM = 10;
// 加载
let that = this;
window.onload = function() {
that.sortImg();
that.lazyLoad();
}
// that.sortImg();
}
appendImg() {
for (var i = 1; i <= 40; i++) {
var imgObj = document.createElement("img");
Object.assign(imgObj, {
className: "item",
src: "../images/" + i + ".jpg"
})
this.boxObj.appendChild(imgObj);
}
}
sortImg() {
// 设置一个空数组存放图片高度
let lineHe = [];
// 遍历图片,判断是否是第一行图片
this.imgsObj = document.querySelectorAll("img");
this.imgsObj.forEach((v, k) => {
if (k < this.columns) { //第一行
v.style.left = (this.imgW + this.leftM) * k + "px";
lineHe.push(v.offsetHeight);
} else { //非第一行
// 找出最短图片
var minIndex = 0;
var min = imgsObj[minIndex];
this.lineHe.forEach((val, key) => {
if (min > key) {
min = key;
minIndex = val;
}
});
// 在最短图片下添加新图片
v.style.left = this.imgsObj[minIndex].offsetLeft + "px"; //确定新图片水平方向的位置
v.style.top = min + this.top + 'px';
// 添加图片后更新其高度
lineHe[minIndex] = lineHe[minIndex] + v.offsetHeight + this.topM;
}
})
}
}
new WaterFall;
</script>
3.无限加载的瀑布流
class WaterFall {
constructor() {
...
window.onload = function() {
that.sortImg();
that.lazyLoad();
}
}
...
lazyLoad() {
let imgArr = ['../images/11.jpg', '../images/14.jpg', '../images/17.jpg', '../images/12.jpg', '../images/18.jpg', '../images/19.jpg'];
// 可视区高度
let cliH = document.body.clientHeight;
// 内容高度=最后一张图片的offsetTop(距离父元素body顶部的距离)
let contentH = this.imgsObj[this.imgsObj.length - 1].offsetTop;
// 滑动滚动条,当可视区高度+滚动条高度>内容高度时,加载新数据
let that = this;
wondow.onsrcoll = function() {
// 滚动调高度(滚动距离)
let st = document.documentElement.scrollTop;
if (st + cliH > contentH) {
imgArr.forEach(v => {
let imgObj = document.createElement("img");
Object.assign(imgObj, {
className: "item",
src: v
})
that.boxObj.appendChild(imgObj);
})
that.sortImg();
}
}
}
}