原生 JavaScript 实现仿百度图片瀑布流布局与滚动加载

桃夭
桃夭
发布时间:2026-10-13| 5人浏览过
原创

本文详解如何使用原生 JavaScript 实现仿百度图片的瀑布流布局。核心逻辑包括计算容器宽度以确定列数、追踪各列高度以实现错位排列,以及利用滚动事件触发数据加载,适用于需要展示大量不规则尺寸图片或卡片的 Web 场景。

结果或目标

最终实现一个包含多个图片的容器,图片按照最小列高原则进行错落排列(即瀑布流效果)。当用户滚动页面至接近底部时,自动从模拟数据源获取新一批图片并追加到页面,同时保持布局的美观与对齐,提升浏览体验。

准备条件

  1. HTML 结构基础:需要一个固定 ID 的主容器 #main,内部放置若干初始图片项,每个图片项需包裹在类名为 .pin 的 div 中,图片本身位于 .box div 内。
  2. CSS 样式支持:父容器相对定位,子元素浮动或绝对定位(脚本会自动处理),设置合理的内外边距以预留空间。
  3. 模拟数据源:由于未连接后端服务器,本文将使用 JavaScript 对象数组 dataInt 来模拟异步加载的数据结构。

真实操作顺序

第1步:构建 HTML 结构与基础 CSS

目的:为 JS 逻辑提供操作的 DOM 节点和视觉基础。

入口:编辑 HTML 文件。

动作:

  1. 创建主容器 <div id="main">。
  2. 在其中放入若干初始 <div class="pin"> 节点,每个节点内含 <div class="box"> 和图片 <img>。
  3. 定义 #main 为相对定位,.pin 左浮动。.box 设置边框、圆角和阴影以增加视觉效果,图片设置为自适应宽度 width: 162px。

第2步:编写核心布局函数 waterfall(parent, pin)

目的:根据当前窗口宽度和图片宽度,计算行数,并将所有图片按“最短列优先”原则重新排列。

入口:调用 waterfall('main', 'pin')。

动作:

  1. 获取元素与宽度:通过 ID 获取父容器 oParent,通过类名获取所有图片列 aPin。获取第一个 .pin 的宽度 iPinW。
  2. 计算列数:num = Math.floor(document.documentElement.clientWidth / iPinW),确定一行能放多少列。
  3. 重置父容器宽度:设置 oParent 宽度为 iPinW * num,并居中显示,确保列宽一致。
  4. 初始化高度数组:pinHArr 用于记录每一列当前的累积高度,长度为 num。
  5. 遍历排列图片:循环遍历所有 .pin 元素:
    • 若索引 i < num,说明是第一行的元素,直接将高度填入 pinHArr[i]。
    • 若 i ≥ num,说明是第二行及以后的元素:
      1. 找出 pinHArr 中的最小值 minH 及其索引 minHIndex。
      2. 将当前图片 aPin[i] 设为 position: absolute。
      3. 设置位置:top 为 minH,left 为该列左侧元素的偏移量 aPin[minHIndex].offsetLeft。
      4. 更新该列高度: pinHArr[minHIndex] += aPin[i].offsetHeight。

第3步:实现滚动检测与数据加载 checkscrollside

目的:判断用户是否已滚动到足够近的位置,以提前加载下一页数据,避免白屏等待。

入口:绑定 window.onscroll 事件。

动作:

  1. 计算临界高度:获取最后一个 .pin 的顶部距离 offsetTop 加上其自身高度的一半。这比直接到底部更早触发,提升流畅度。
  2. 获取当前滚动状态:兼容获取 scrollTop 和可视区域高度 clientHeight。
  3. 判断逻辑:如果 lastPinH < scrollTop + documentH,返回 true,表示满足加载条件。

第4步:整合数据注入与重排

目的:在滚动触发后,将模拟数据转化为 DOM 节点并刷新布局。

入口:window.onload 中初始化。

动作:

  1. 定义模拟数据 var dataInt = { 'data': [...] }。
  2. 在 window.onscroll 回调中调用 checkscrollside()。
  3. 若为真,遍历数据数组:
    <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 实现仿百度图片瀑布流加载效果的详细内容,更多关于前端开发中实现复杂布局与交互技巧的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。