最可控的图片批量操作方式是用 document.queryselectorall 选中带语义标记的元素,如 img[data-album="vacation-2023"];picture 元素必须按 avif→webp→jpg 顺序书写 source;onerror 是唯一有效的 html 层加载失败捕获机制;grid 布局应使用 auto-fit + minmax() 实现响应式相册网格。

用 document.querySelectorAll 批量选中带语义标记的图片
直接操作 DOM 是最可控的方式,但别用 getElementsByClassName ——它返回实时 NodeList,循环中增删 class 可能漏改或重复遍历。优先锁定有明确业务标识的元素,比如 document.querySelectorAll('img[data-album="vacation-2023"]') 或 document.querySelectorAll('figure[data-category="landscape"]')。
这样做的好处是:修改范围精准、不污染全局、后续加 JS 逻辑(如懒加载开关、格式降级)也容易统一注入。如果所有图都塞进一个 .gallery 容器再用 .gallery img 选,一旦页面里混入其他图(比如广告位),就容易误伤。
批量生成 picture 元素必须按 avif → webp → jpg 顺序写 source
浏览器对 <source></source> 的解析是“从上到下匹配首个支持且满足 media/sizes 条件的”,不是“选最优”。Safari 尤其敏感:如果 type="image/avif" 的 <source></source> 放在后面,它可能直接跳过,哪怕前面的 webp 也不认。
实操建议:
- 每个图的配置对象至少含
src(JPG)、webp、avif、sizes四个字段,缺一不可 - 生成时严格按
<source type="image/avif"></source>→<source type="image/webp"></source>→<img src="...">顺序插入 - 别在循环里反复调用
document.createElement('picture')后立刻appendChild,改用DocumentFragment收集完再挂载,避免多次重排
onerror 是唯一能在 HTML 层捕获加载失败的机制
CSS 的 ::after 或背景图 fallback 对图片加载失败完全无效;onerror 虽然只响应网络错误(404、CORS、跨域拒绝),但它能第一时间触发替换逻辑,比 JS 全局轮询更轻量。
常见踩坑点:
- 写成
<img src="x.jpg" onerror="this.style.display='none'">最简兜底,但无法复用逻辑 - 更稳妥的是
onerror="this.src='placeholder.svg'; this.title='加载失败: '+this.src;",注意引号嵌套别出错 - 千万别在
onerror里调用未定义函数(比如onerror="handleError()"却没声明handleError),会中断后续所有图片的错误处理 - 本地双击打开
file://协议时,部分浏览器对跨目录路径的onerror不触发,上线前务必用本地服务器测试
Grid 布局必须用 auto-fit + minmax(),别碰 flex-wrap
Flex 布局做相册网格,最后一行经常只剩 1–2 张图,左右留白、间隙不均,尤其图片原始宽高比不一致时更明显。Grid 的 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) 才是解法。
关键细节:
- 必须设
gap(不是 margin),否则空隙靠边距模拟会破坏网格对齐 -
minmax(280px, 1fr)中的 280px 是最小列宽,低于该值就自动减少列数,不是固定像素值 - 每张图必须包在
<figure></figure>里,<img>单独设width: 100%; height: auto;,禁止设固定height,否则小图被拉伸变形 - IE10+ 需用
grid-column-gap和grid-row-gap替代gap,但现代项目基本可忽略
路径问题永远是第一排查项:所有图片路径必须以 HTML 文件所在目录为基准,统一用 ./photos/xxx.jpg 这种相对写法,混用 images/ 和 ./images/ 在嵌套路由下必炸。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











