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 即可自适应
相关推荐
重铸码农荣光11 小时前
从「[1,2,3].map (parseInt)」踩坑,吃透 JS 数组 map 与包装类核心逻辑
面试·node.js
零号机11 小时前
使用TRAE 30分钟极速开发一款划词中英互译浏览器插件
前端·人工智能
molly cheung11 小时前
FetchAPI 请求流式数据 基本用法
javascript·fetch·请求取消·流式·流式数据·流式请求取消
疯狂踩坑人11 小时前
结合400行mini-react代码,图文解说React原理
前端·react.js·面试
Mintopia11 小时前
🚀 共绩算力:3分钟拥有自己的文生图AI服务-容器化部署 StableDiffusion1.5-WebUI 应用
前端·人工智能·aigc
街尾杂货店&11 小时前
CSS - transition 过渡属性及使用方法(示例代码)
前端·css
CH_X_M12 小时前
为什么在AI对话中选择用sse而不是web socket?
前端
Mintopia12 小时前
🧠 量子计算对AIGC的潜在影响:Web技术的未来可能性
前端·javascript·aigc
街尾杂货店&12 小时前
css - word-spacing 属性(指定段字之间的间距大小)属性定义及使用说明
前端·css
忧郁的蛋~12 小时前
.NET异步编程中内存泄漏的终极解决方案
开发语言·前端·javascript·.net