原生 JavaScript 实现仿百度图片瀑布流布局与滚动加载
本文详解如何使用原生 JavaScript 实现仿百度图片的瀑布流布局。核心逻辑包括计算容器宽度以确定列数、追踪各列高度以实现错位排列,以及利用滚动事件触发数据加载,适用于需要展示大量不规则尺寸图片或卡片的 Web 场景。
结果或目标
最终实现一个包含多个图片的容器,图片按照最小列高原则进行错落排列(即瀑布流效果)。当用户滚动页面至接近底部时,自动从模拟数据源获取新一批图片并追加到页面,同时保持布局的美观与对齐,提升浏览体验。
准备条件
- HTML 结构基础:需要一个固定 ID 的主容器
#main,内部放置若干初始图片项,每个图片项需包裹在类名为.pin的 div 中,图片本身位于.boxdiv 内。 - CSS 样式支持:父容器相对定位,子元素浮动或绝对定位(脚本会自动处理),设置合理的内外边距以预留空间。
- 模拟数据源:由于未连接后端服务器,本文将使用 JavaScript 对象数组
dataInt来模拟异步加载的数据结构。
真实操作顺序
第1步:构建 HTML 结构与基础 CSS
目的:为 JS 逻辑提供操作的 DOM 节点和视觉基础。
入口:编辑 HTML 文件。
动作:
- 创建主容器
<div id="main">。 - 在其中放入若干初始
<div class="pin">节点,每个节点内含<div class="box">和图片<img>。 - 定义
#main为相对定位,.pin左浮动。.box设置边框、圆角和阴影以增加视觉效果,图片设置为自适应宽度width: 162px。
第2步:编写核心布局函数 waterfall(parent, pin)
目的:根据当前窗口宽度和图片宽度,计算行数,并将所有图片按“最短列优先”原则重新排列。
入口:调用 waterfall('main', 'pin')。
动作:
- 获取元素与宽度:通过 ID 获取父容器
oParent,通过类名获取所有图片列aPin。获取第一个.pin的宽度iPinW。 - 计算列数:
num = Math.floor(document.documentElement.clientWidth / iPinW),确定一行能放多少列。 - 重置父容器宽度:设置
oParent宽度为iPinW * num,并居中显示,确保列宽一致。 - 初始化高度数组:
pinHArr用于记录每一列当前的累积高度,长度为num。 - 遍历排列图片:循环遍历所有
.pin元素:- 若索引
i < num,说明是第一行的元素,直接将高度填入pinHArr[i]。 - 若
i ≥ num,说明是第二行及以后的元素:- 找出
pinHArr中的最小值minH及其索引minHIndex。 - 将当前图片
aPin[i]设为position: absolute。 - 设置位置:
top为minH,left为该列左侧元素的偏移量aPin[minHIndex].offsetLeft。 - 更新该列高度:
pinHArr[minHIndex] += aPin[i].offsetHeight。
- 找出
- 若索引
第3步:实现滚动检测与数据加载 checkscrollside
目的:判断用户是否已滚动到足够近的位置,以提前加载下一页数据,避免白屏等待。
入口:绑定 window.onscroll 事件。
动作:
- 计算临界高度:获取最后一个
.pin的顶部距离offsetTop加上其自身高度的一半。这比直接到底部更早触发,提升流畅度。 - 获取当前滚动状态:兼容获取
scrollTop和可视区域高度clientHeight。 - 判断逻辑:如果
lastPinH < scrollTop + documentH,返回true,表示满足加载条件。
第4步:整合数据注入与重排
目的:在滚动触发后,将模拟数据转化为 DOM 节点并刷新布局。
入口:window.onload 中初始化。
动作:
- 定义模拟数据
var dataInt = { 'data': [...] }。 - 在
window.onscroll回调中调用checkscrollside()。 - 若为真,遍历数据数组:
<pre><code> for(var i=0; i<dataInt.data.length; i++) { // 创建 .pin -> .box -> img 的 DOM 树 // 设置 src 为 './images/' + dataInt.data[i].src // 依次 appendChild 到 #main } // 注入完成后,再次调用 waterfall('main', 'pin') 重新计算布局 </code></pre>
通过上述步骤,即可在没有后端支持的情况下,在本地浏览器中体验到完整的瀑布流无限滚动效果。
完成判断
- 视觉检查:所有图片紧密排列,无明显空隙,不同高度的图片错落有致。
- 交互检查:向下滚动鼠标滚轮或触摸滑动,当页面接近底部时,新图片自动出现并立即填入正确位置,不会导致页面抖动过大。
- 兼容性检查:调整浏览器窗口大小,重新加载或触发重排后,列数应根据新的屏幕宽度自动增减。
原文有依据的排错
- 图片加载时机:如果图片尚未完全下载就执行布局计算,可能导致高度
offsetHeight读取错误。在生产环境中,应监听onload或在图片资源就绪后再调用布局函数。 - 重复滚动触发:原代码在每次滚动都检查全量数据。若数据量大,建议添加锁标志(Lock),防止在 AJAX 请求期间重复触发加载。
简要总结
原生 JavaScript 实现瀑布流的核心在于“计算列数”与“追踪列高”。通过简单的数学运算将绝对定位的元素放置在最短的列下,再辅以滚动事件的监听,就能构建出高性能且无依赖的图文展示方案。
以上就是原生 JavaScript 实现仿百度图片瀑布流加载效果的详细内容,更多关于前端开发中实现复杂布局与交互技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









