最轻量可靠的图片预览方案是用+javascript按需加载单张图,禁用setinterval轮播逻辑;需设置document.body.style.overflow = 'hidden'和dialogel.focus()以保障滚动锁定与键盘可访问性。

直接用 <dialog></dialog> + JavaScript 控制图片加载,是目前最轻量、最可靠的做法。别碰 setInterval 轮播那种“伪自动播放”,那不是预览,是轮播图。
为什么不能用轮播逻辑做预览
预览的核心诉求是「按需加载、单张聚焦、用户主导」,而轮播的 setInterval 或 CSS @keyframes 会提前加载、自动切换、无视用户停留意图。常见问题包括:
- 用户刚点开一张图,0.5 秒后就切走——体验断裂
- 多图预览时,
setInterval定时器未清理导致内存泄漏或错乱索引 - CSS 动画方式无法响应点击/ESC/键盘操作,无障碍支持为零
- 原图还没加载完就切到下一张,显示空白或 fallback 缩略图
<dialog></dialog> 预览必须补的两行 JS
现代浏览器(Chrome 98+、Firefox 111+、Edge 98+)原生支持 <dialog></dialog>,但默认不接管焦点和滚动。漏掉以下任一,预览就会出问题:
-
document.body.style.overflow = 'hidden';—— 否则背景仍可滚动,尤其在 macOS Safari 上极其明显 -
dialogEl.focus();—— 否则 Tab 键焦点留在背景页,键盘用户无法操作关闭按钮或箭头切换
关闭时记得还原:document.body.style.overflow = '';
原图地址怎么存、怎么加载才对
data-fullsrc 不是随便塞个 URL 就行。常见错误是把几 MB 的高清图地址直接写死在 HTML 里,导致首屏加载巨慢。
- 缩略图用
loading="lazy"+ 显式width/height,防布局抖动 - 原图地址存在
data-fullsrc,但只在用户点击后才执行:const img = new Image(); img.src = fullsrc; - 加载失败时,
img.onerror回退到当前缩略图的src,别留空 - 如果服务端返回的是 JSON(如
{thumb: "...", medium: "...", original: "..."}),优先取original;没有就退到medium,并在 UI 标注 “非原始尺寸”
移动端手势和焦点顺序容易被忽略
在 iOS Safari 和 Android Chrome 上,<dialog></dialog> 内部图片若没设 touch-action: pan-x pan-y;,双指缩放或拖拽会触发页面整体缩放或滚动,预览框直接卡死。
焦点顺序也关键:关闭按钮(×)必须是第一个可聚焦元素,接着是图片本身(用于键盘放大/下载),最后才是左右箭头。别依赖 autofocus,它在 <dialog></dialog> 中行为不可靠,手动 .focus() 才稳。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











