图片预览手机适配 + 正文图统一接入 lightbox
- lightbox:打开锁背景滚动(手机上背景不再跟着滑)、手机滑动左右翻页、 dvh 跟随全面屏可视高度、关闭钮/角标走 safe-area、图片全宽无圆角 - 全局 capture 委托:时间线/详情页 v-html 正文里的图统一可点开预览, capture+stop 压住整卡跳转;thumbifyHtml 把原图地址留在 data-fullsrc, 预览用原图而非 480w 缩略图;链接卡缩略图不劫持(点击仍是打开链接)
This commit is contained in:
+25
-2
@@ -7,9 +7,26 @@ import ImgLightbox from './components/ImgLightbox.vue'
|
||||
import YohakuTop from './ui/yohaku/YohakuTop.vue'
|
||||
import YohakuFoot from './ui/yohaku/YohakuFoot.vue'
|
||||
import { site, setAdminScope } from './site'
|
||||
import { openLightbox } from './lightbox'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// 正文图片点击预览(capture 阶段):时间线/详情页里 v-html 的正文图
|
||||
// 都没有自己的点击入口,这里统一接管。capture + stopPropagation 是为了
|
||||
// 压住整卡点击(时间线点图不该跳详情);配图网格有自己的 handler 不在
|
||||
// .prose 内,天然不受影响。lightbox 用 data-fullsrc 原图(thumbify 保留)。
|
||||
function onProseImgClick(e) {
|
||||
const img = e.target
|
||||
if (!img || img.tagName !== 'IMG') return
|
||||
const scope = img.closest('.prose')
|
||||
if (!scope || img.closest('.post-imgs') || img.closest('a')) return
|
||||
const list = [...scope.querySelectorAll('img')].map((i) => i.dataset.fullsrc || i.currentSrc || i.src)
|
||||
const cur = img.dataset.fullsrc || img.currentSrc || img.src
|
||||
const idx = Math.max(0, list.indexOf(cur))
|
||||
e.stopPropagation()
|
||||
openLightbox(list, idx)
|
||||
}
|
||||
|
||||
// 正文代码块复制按钮(事件委托:复制按钮是 enhanceProse 注入的静态 HTML)
|
||||
function onCopyClick(e) {
|
||||
const btn = e.target.closest?.('.pre-copy')
|
||||
@@ -31,8 +48,14 @@ function onCopyClick(e) {
|
||||
setTimeout(() => (btn.textContent = '复制'), 1600)
|
||||
})
|
||||
}
|
||||
onMounted(() => document.addEventListener('click', onCopyClick))
|
||||
onBeforeUnmount(() => document.removeEventListener('click', onCopyClick))
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', onCopyClick)
|
||||
document.addEventListener('click', onProseImgClick, true)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', onCopyClick)
|
||||
document.removeEventListener('click', onProseImgClick, true)
|
||||
})
|
||||
|
||||
const isAdmin = computed(() => route.path.startsWith('/admin'))
|
||||
// vivid 只在公开前台生效:后台永远走 classic 那套(--admin-* token + 原 data-ui/data-theme),
|
||||
|
||||
Reference in New Issue
Block a user