import PhotoSwipe from 'https://dpangzi.com/library/photoswipe/photoswipe.esm.min.js';
let photoViewer = null;
let pswpRoot = null;
function ensureRoot() {
if (pswpRoot) return pswpRoot;
pswpRoot = document.createElement('div');
pswpRoot.className = 'pswp';
document.body.appendChild(pswpRoot);
return pswpRoot;
}
export function initPhotoViewer() {
const photoPreview = document.getElementById('photoPreview');
if (!photoPreview) return;
// 已有图片则直接绑定
if (photoPreview.src) {
bindPreviewClick(photoPreview);
}
}
function bindPreviewClick(img) {
img.removeEventListener('click', handlePreviewClick);
img.addEventListener('click', handlePreviewClick);
}
function handlePreviewClick(event) {
event.preventDefault();
const img = event.currentTarget;
openPhotoSwipe(img);
}
export function openPhotoSwipe(imgElement) {
const src = imgElement?.src;
if (!src) return;
const width = imgElement.naturalWidth || 1920;
const height = imgElement.naturalHeight || 1080;
const pswp = new PhotoSwipe({
dataSource: [{ src, width, height }],
index: 0,
showHideAnimationType: 'fade',
bgOpacity: 0.88,
escKey: true,
returnFocus: false,
zoom: false,
pswpElement: ensureRoot()
});
pswp.init();
photoViewer = pswp;
return pswp;
}
export function destroyPhotoViewer() {
if (photoViewer && typeof photoViewer.destroy === 'function') {
photoViewer.destroy();
}
photoViewer = null;
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
下面按要点解释这段代码在做什么、各函数的职责、关键配置含义以及一些使用/改进建议。
概览
- 这个模块把 PhotoSwipe(一个图片预览/查看器库)以 ES 模块方式引入,并提供初始化、打开和销毁查看器的功能。
- 主要用法:页面上有一个 id 为 photoPreview 的 img 元素时,调用 initPhotoViewer 会给它绑定点击事件,点击图片就用 PhotoSwipe 打开预览(单张图)。
逐函数说明
import PhotoSwipe from '...':
- 引入 PhotoSwipe 的 ESM 构建(路径为外部 URL)。
let photoViewer = null, let pswpRoot = null:
- 模块级变量,保存已打开的 PhotoSwipe 实例和用于挂载的 DOM 根节点。
ensureRoot():
- 如果已经创建并缓存了 pswpRoot,直接返回。
- 否则创建一个 div,class 为 'pswp',追加到 document.body,并返回该节点。
- 这个节点作为 PhotoSwipe 的容器(pswpElement)。
initPhotoViewer():
- 查找页面上 id 为 'photoPreview' 的 img 元素。
- 若不存在则返回(不做任何事情)。
- 若该 img 有 src,则调用 bindPreviewClick 给它绑定点击事件。
bindPreviewClick(img):
- 先 removeEventListener('click', handlePreviewClick)(防止重复绑定),再 addEventListener 绑定点击处理函数。
- 通过事件委托的方式把点击交给 handlePreviewClick。
handlePreviewClick(event):
- 阻止默认行为(event.preventDefault())。
- 从 event.currentTarget 取到被点击的元素(img),然后调用 openPhotoSwipe 打开查看器。
openPhotoSwipe(imgElement):
- 读取 imgElement.src(找不到就直接返回)。
- 获取图片实际尺寸:naturalWidth / naturalHeight,若没有则用 1920x1080 作为默认值。
- 使用 new PhotoSwipe({...}) 创建查看器实例,dataSource 只包含一张图片(单张预览)。
- 传入一系列选项(见下文),并把 pswpElement 指向 ensureRoot() 返回的 DOM。
- 调用 pswp.init() 打开查看器,把实例保存到模块变量 photoViewer,并返回这个实例。
destroyPhotoViewer():
- 如果存在 photoViewer 并且有 destroy 方法,则调用它销毁查看器。
- 将 photoViewer 置为 null(但不移除 pswpRoot DOM 节点)。
关键配置说明(在 new PhotoSwipe({...}) 中)
- dataSource: [{ src, width, height }]:传入要显示的图片及其宽高(这里是单张)。
- index: 0:默认打开第 0 张。
- showHideAnimationType: 'fade':打开/关闭时使用淡入淡出动画。
- bgOpacity: 0.88:背景遮罩不透明度。
- escKey: true:允许用 Esc 关闭。
- returnFocus: false:关闭后不自动把焦点返回到之前的元素(可用于避免某些焦点问题)。
- zoom: false:禁用放大/缩放手势(无法缩放图片)。
- pswpElement: ensureRoot():指定 PhotoSwipe 渲染的 DOM 容器。
使用注意和改进建议
- 仅支持页面上 id 为 photoPreview 的单张图片;要支持多张或动态图片需修改逻辑(遍历集合或根据 data 属性构建 dataSource)。
- ensureRoot 创建的 pswp 根节点在 destroyPhotoViewer 中没有移除,可能留在 DOM 中;可以在销毁时同时移除该节点并把 pswpRoot 置 null。
- 如果图片尚未加载(naturalWidth/naturalHeight 为 0),会使用默认 1920x1080,可能导致尺寸不准确。可在打开前确保图片已加载(检查 complete 或监听 load)。
- 绑定事件时用 removeEventListener 防止重复绑定,但要保证传入的 handler 是同一个引用(这里是同一个函数引用,符合要求)。
- 若页面动态插入 img,需要在插入后调用 initPhotoViewer 或提供外部调用 openPhotoSwipe 的入口(模块已导出 openPhotoSwipe)。
- 可增加错误处理(例如图片 URL 无效、PhotoSwipe 创建失败等)。
- 如果需要缩放功能,把 zoom: false 改为 true 并确保提供合适的宽高/高分辨率图源。
总结 这段代码的目的是为页面上的一个图片(id=photoPreview)提供单张的 PhotoSwipe 预览体验:点击图片时创建并打开 PhotoSwipe 查看器,查看器配置了遮罩、淡入动画、禁用缩放等选项,并提供了销毁实例的函数。代码结构清晰,但在多图、动态加载、DOM 清理、尺寸准确性等方面还有可改进之处。
评论加载中...