JavaScript 实现瀑布流布局与无限滚动加载详解

作者:拾光时间:2026-10-24 08:56:32浏览:237

本文详细介绍如何使用 JavaScript 实现网页瀑布流布局及无限滚动加载功能。核心思路包括绑定滚动事件、判断页面是否触底以及动态渲染新数据,旨在为前端开发者提供可直接运行的完整代码示例与逻辑解析。

JavaScript 瀑布流布局实现概述

本文分享了一段使用 JavaScript 实现瀑布流布局的具体代码示例,供读者参考学习。

瀑布流布局核心逻辑

首先梳理实现瀑布流布局的核心逻辑步骤。

在数据准备就绪后,进入具体实现环节。

具体实现步骤如下: 1. 绑定页面滚动事件。 2. 判断页面是否滚动到底部(通过计算滚动距离加上可视区域高度,判断是否等于最后一个元素的 top 值)。 3. 加载新数据并渲染页面。 4. 重新执行瀑布流布局效果。

完整代码示例

以下是完整代码实现(替换图片路径后即可直接运行测试)。


<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 .cont{margin: 0 auto;background: #ccc;position: relative;}
 .cont::after{content: "";display: block;clear: both;}

 .box{float: left;padding: 6px;}

 .imgbox{border: solid 1px black;padding: 6px;border-radius: 6px;}
 
 .imgbox img{width: 200px;display: block;}
 </style>
 <script src="data/data.js"></script>
 <script>
 // W1. 准备数据
 // W2. 绑定滚动事件
  // W3. 判断页面是否到底(滚动的距离+可是区域的高度 == 最后一个元素的top)
  // W4. 加载新数据,渲染新页面
  // W5. 重新执行瀑布流效果
 onload = function(){
  new Waterfall;
 }
 class Waterfall{
  constructor(){
  // 1.选择元素
  this.box = document.querySelectorAll(".box");
  this.cont = document.querySelector(".cont");
  this.clientH = document.documentElement.clientHeight;
  this.heightArr = [];
  // 2.补全布局
  this.init();
  this.addEvent();
  }
  addEvent(){
  var that = this;
  onscroll = function(){
   var scrollT = document.documentElement.scrollTop;
   if(that.clientH + scrollT > that.scrollH-300){
   that.render()
   }
  }
  }
  render(){
  for(var i=0;i<data.length;i++){
   var img = document.createElement("img")
   img.src = data[i].src;
   var imgbox = document.createElement("div")
   imgbox.className = "imgbox";
   var box = document.createElement("div")
   box.className = "box";
   imgbox.appendChild(img);
   box.appendChild(imgbox);
   this.cont.appendChild(box);
  }
  // 初始化所有
  this.box = document.querySelectorAll(".box");
  this.heightArr = [];
  // 重新渲染瀑布流结构
  this.firstLine();
  this.otherLine();
  }
  init(){
  // 计算一行最多能放几个,再计算最大宽度
  this.clientW = document.documentElement.clientWidth;
  this.boxW = this.box[0].offsetWidth;
  this.maxNum = parseInt(this.clientW / this.boxW)
  this.cont.style.width = this.boxW * this.maxNum + "px";

  // 3. 区分第一行
  this.firstLine()
  // 4. 区分其他行
  this.otherLine();
  }
  firstLine(){
  // 5. 获取所有元素的高度,存起来
  for(var i=0;i<this.maxNum;i++){
   this.heightArr.push(this.box[i].offsetHeight);
  }
  }
  otherLine(){
  for(var i=this.maxNum;i<this.box.length;i++){
   // 6. 拿到第一行所有的高度
   // console.log(this.heightArr)
   // 计算最小值和最小值的索引
   // var min = getMin(this.heightArr);
   // var min = Math.min.apply(null,this.heightArr);
   var min = Math.min(...this.heightArr);
   var minIndex = this.heightArr.indexOf(min);
   // console.log(minIndex);
   // 7. 设置元素的定位
   this.box[i].style.position = "absolute";
   // 8. 设置元素的top和left
   this.box[i].style.top = min + "px";
   this.box[i].style.left = minIndex * this.boxW + "px";
   // 9. 修改最小值
   this.heightArr[minIndex] += this.box[i].offsetHeight;
  }
  this.scrollH = document.documentElement.scrollHeight;
  }
 }
 function getMin(arr){
  // 先对数组进行截取(为了深拷贝)
  // 然后对截取出的新数组排序
  // 找第0位
  // 返回出去
  return arr.slice(0).sort((a,b)=>a-b)[0];
 }
 
 </script>
</head>
<body>
 <div class="cont">
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/4.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/2.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/3.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/5.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/1.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/6.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/7.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/8.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/9.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/10.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/4.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/2.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/3.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/5.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/1.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/6.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/7.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/8.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/9.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/10.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/4.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/2.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/3.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/5.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/1.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/6.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/7.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/8.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/9.jpg" alt="">
  </div>
 </div>
 <div class="box">
  <div class="imgbox">
  <img src="../imgs/10.jpg" alt="">
  </div>
 </div>
 </div>
</body>
</html>

以上内容为本文的全部介绍,希望能为读者提供有益的帮助,也欢迎大家继续支持本站。

作者最新文章