JS 实现图片瀑布流布局

瀑布流 = 定宽 + 不定高 + 列内追加。本文用原生js代码实现完整布局、重排、防抖,不依赖任何库。

一、核心思路

  1. 计算列数 = 容器宽 ÷ 图片宽
  2. 维护数组 colH[] = 每列当前高度
  3. 每张图找 最小高度 那一列塞进去
  4. 更新 colH[col] += 图片高 + 间隙
  5. 窗口 resize → 防抖重新布局

二、核心代码速览

js 复制代码
// ① 定宽
const imgW = 220                                                    
const container = document.getElementById('container')

// ② 列数 & 间隙
function cal() {                                                    
  const cw = container.clientWidth
  const cols = Math.floor(cw / imgW)
  const space = (cw - cols * imgW) / (cols + 1)
  return { cols, space }
}

 // ③ 布局函数
function setPos() {                                                
  const { cols, space } = cal()
  const colH = new Array(cols).fill(0)                              

  // 列高数组
  Array.from(container.children).forEach(img => {
    const minH = Math.min(...colH)
    const col = colH.indexOf(minH)
    img.style.top = minH + 'px'
    img.style.left = (col + 1) * space + col * imgW + 'px'
     // 更新列高
    colH[col] += img.height + space                               
  })

  // 撑开容器
  container.style.height = Math.max(...colH) + 'px'                
}

 // ④ 动态插入
function createImgs() {                                            
  for (let i = 0; i <= 40; i++) {
    const img = new Image()
    img.src = `../img/${i}.jpg`
    img.style.width = imgW + 'px'
    // 每张图加载完就排
    img.onload = setPos                                            
    container.appendChild(img)
  }
}

let timeId = null
// ⑤ 防抖重排
window.onresize = () => {                                           
  clearTimeout(timeId)
  timeId = setTimeout(setPos, 500)
}

// ⑥ 启动
createImgs()                                                        

三、关键点解读

  • 定宽不定高:imgW 固定,height 由图片本身决定
  • 列高数组:colH[col] 永远保存当前列的累计高度
  • DOM 移动:appendChild 不会重复插入,只做位置重排
  • 防抖:500 ms 内多次 resize 只执行最后一次,避免卡顿

四、性能 & 扩展

  • 零依赖:gzip < 1 KB,适用于任何老项目
  • 可异步:把 createImgs 换成 fetch 即可接入后端分页
  • 可响应:把 imgW 换成百分比,cal() 里用 clientWidth * ratio 即可自适应
相关推荐
再吃一根胡萝卜5 小时前
08 · 前端:Vue3 + SSE 流式与执行链路可视化
面试
再吃一根胡萝卜5 小时前
03 · 后端:FastAPI 与分层架构
面试
mldong6 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排7 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60617 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角8 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!8 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰9 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
Interview Aid1129 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
mayaairi10 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js