前言
Vuepress默认的图片浏览是点击放大,可以说是非常简洁,如果网站图片比较多,还是可以加载Fancybox来使它更加优雅。
因为我不喜欢把一大堆包都放在服务器,直接从CDN引入,自动加载其最新版本,这样省去很多后期维护成本。
这篇文章介绍一下这种最简单的方法让Vuepress网站使用Fancybox。
图片步骤(已验证)
-
创建fancybox插件
在
docs/.vuepress/plugins
目录中创建一个名为vuepress-plugin-fancybox
的目录,如果没有plugins
目录,先创建此目录;在
vuepress-plugin-fancybox
目录下,添加名为index.js
的文件,将下面内容添加进去:// docs/.vuepress/plugins/vuepress-plugin-fancybox/index.js export default () => ({ name: 'vuepress-plugin-fancybox', extendsMarkdown(md) { md.renderer.rules.image = function (tokens, idx, options, env, self) { const token = tokens[idx] const srcIndex = token.attrIndex('src') const src = token.attrs[srcIndex][1] const alt = token.content || '' // 使用页面路径作为 gallery 名称,避免跨页面冲突 const galleryName = (env.relativePath || 'gallery') .replace(/\//g, '-') .replace(/\.\w+$/, '') return `<a href="${src}" data-fancybox="${galleryName}"><img src="${src}" alt="${alt}"></a>` } }, })
-
修改
docs/.vuepress/config.js
配置文件对应栏目添加以下内容:
// docs/.vuepress/config.js import { viteBundler } from '@vuepress/bundler-vite' import { defaultTheme } from '@vuepress/theme-default' //..省略..// import fancyboxPlugin from './plugins/vuepress-plugin-fancybox/index.js' export default defineUserConfig({ //..省略..// head: [ ['link', { rel: 'stylesheet', href: 'https://unpkg.com/@fancyapps/ui/dist/fancybox/fancybox.css' }], ['script', { src: 'https://unpkg.com/@fancyapps/ui/dist/fancybox/fancybox.umd.js' }], ['script', {}, ` document.addEventListener('DOMContentLoaded', () => { if (window.Fancybox) { window.Fancybox.bind('[data-fancybox]'); } }); `], //..省略..// ], //..省略..// plugins: [ fancyboxPlugin(), //..省略..// ], })
-
构建网站
最后使用
npm run docs:build
或者npm run docs:dev
进行调试。
同时处理图片以及视频(未验证)
Fancybox给我最大的亮点是使用下面代码可以播放视频:
<a href="/sample.mp4" data-fancybox data-width="640" data-height="360">
<img src="/poster.jpg" alt="Video poster" width="240" height="180" />
</a>
提供一个思路,修改 docs/.vuepress/plugins/vuepress-plugin-fancybox/index.js
的代码:
// docs/.vuepress/plugins/vuepress-plugin-fancybox/index.js
export default () => ({
name: 'vuepress-plugin-fancybox',
extendsMarkdown(md) {
md.renderer.rules.image = function (tokens, idx, options, env, self) {
const token = tokens[idx]
const srcIndex = token.attrIndex('src')
const src = token.attrs[srcIndex][1]
const alt = token.content || ''
const galleryName = (env.relativePath || 'gallery')
.replace(/\//g, '-')
.replace(/\.\w+$/, '')
// 判断是否是视频
const isVideo = /\.(mp4|webm|ogg)$/i.test(src)
if (isVideo) {
// 动态计算屏幕尺寸
const width = window.innerWidth * 0.8 // 自适应 80% 屏幕宽度
const height = window.innerHeight * 0.8 // 自适应 80% 屏幕高度
return `<a href="${src}" data-fancybox="${galleryName}" data-width="${width}" data-height="${height}">
<img src="${token.attrs[srcIndex][1]}" alt="${alt}" />
</a>`
}
// 默认渲染图片
return `<a href="${src}" data-fancybox="${galleryName}"><img src="${src}" alt="${alt}"></a>`
}
},
})
不想弄视频的原因是需要给每个视频添加缩略图啥的,太麻烦,而且要考虑markdown的书写方式,图片和视频怎么写,怎么判断它是超链接还是图片,还是视频,缩略图怎么加,我这边也只是给个大致方向。不管出于什么原因,都不建议把视频加上。
最后
要说一个比较让我有点不习惯的地方:比如一个网页有很多图片,通过Fancybox浏览到其他一张图片,在这个位置关掉图片,那么页面会自动滚动到此时图片所在的位置。
不过这个也可以进行关闭:
// docs/.vuepress/config.js
['script', {}, `
document.addEventListener('DOMContentLoaded', () => {
if (window.Fancybox) {
window.Fancybox.bind('[data-fancybox]', {
placeFocusBack: false //添加这个
});
}
});
`],
其他的完全没问题。