用 + javascript 实现点击切换需将图片地址存数组,每项含 src、srcset、sizes;初始及切换时同步设置 的三者属性,读取 data-srcset-n 等预存属性确保响应式不丢失,边界作循环或禁用处理,并适配移动端 touch 事件。

用 <picture></picture> + JavaScript 实现点击切换,别用 <img srcset> 做切换逻辑
<img srcset> 是给浏览器看的——它让浏览器根据屏幕宽度、像素密度自动选一张最合适的图加载,但不会帮你“换图”。想点一下切下一张,必须用 JS 控制 src 或 srcset 属性。推荐把所有图片地址存在数组里,用一个索引变量控制当前显示哪张。
常见错误是直接监听 click 后写死 img.src = 'a.jpg';,结果响应式失效:小屏设备加载了大图,浪费带宽;或者没同步更新 srcset 和 sizes,导致高 DPR 设备显示模糊。
- 把图片列表存成数组,每项包含
src、srcset、sizes(可选),甚至alt - 初始渲染时,用 JS 设置
<img>的src、srcset、sizes三者,确保响应式能力不丢 - 切换时,只改这三项,不要只改
src
用 data- 属性预存多套 srcset,避免重复拼接字符串
如果每张图的 srcset 规则不同(比如有的要适配 1x/2x,有的还要加 320w/768w 断点),硬编码在 JS 里容易出错、难维护。更稳妥的做法是在 HTML 里用 data-srcset-0、data-srcset-1 等属性提前存好:
@@##@@
JS 切换时,读取对应索引的 data-srcset-N 和 data-sizes-N,再一次性赋值,比用模板字符串拼更可靠。
- 注意:IE 不支持
srcset,但现代项目基本不用考虑;如需兼容,可用picturefillpolyfill -
sizes必须和srcset匹配,否则浏览器无法正确计算“该加载哪份资源” - 不要在 JS 中动态生成
srcset字符串(比如arr.map(...).join(', ')),易漏空格或单位,直接存完整字符串最稳
处理边界:点击最后一张后点“下一张”,应该循环回第一张还是停住?
这个不是技术问题,是交互预期问题,但很多人忽略它,导致用户狂点没反应,以为卡了。必须明确行为并实现一致:
- 循环切换:索引用
(index + 1) % images.length,简单干净 - 停在末尾:检查
if (currentIndex 再递增,否则什么也不做(或禁用按钮) - 更友好做法:末尾时把“下一张”按钮
disabled,或视觉置灰;首张时同理处理“上一张”
别依赖 CSS :disabled 默认样式,加个类名 is-disabled 更可控,也方便后续加 Tooltip 提示“已是最后一张”。
移动端要注意 touch 事件冲突和双击缩放干扰
纯 click 在 iOS 上有约 300ms 延迟,且双击可能触发页面缩放(尤其 <meta name="viewport"> 配置不当时)。解决方案很直接:
- 加
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">防双击缩放 - 监听
touchend替代click,但要加preventDefault()防止滚动穿透(尤其图在滚动容器内时) - 为防误触,可加
touchstart记录起始位置,touchend时判断位移
真没必要引入 Hammer.js 这类库——就一个图切换功能,手写 20 行事件逻辑足够,还少一个依赖、少一个兼容性坑。
最容易被忽略的是:切换图片后,<img id="gallery-img" src="photo-0-small.jpg" data-srcset-0="photo-0-small.jpg 480w, photo-0-medium.jpg 768w, photo-0-large.jpg 1200w" data-srcset-1="photo-1-thumb.jpg 320w, photo-1-main.jpg 1024w" data-sizes-0="(max-width: 768px) 100vw, 50vw" data-sizes-1="100vw" alt="第一张图"> 的 naturalWidth/naturalHeight 不会立刻更新,如果你靠它算缩放比例或裁剪位置,得等 load 事件后再执行。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











