feat(ui): PostCard 详情页新增浏览量显示

This commit is contained in:
Ad-closeNN
2026-04-19 22:58:21 +08:00
parent 27a6f94f64
commit 65dc754cae
4 changed files with 152 additions and 29 deletions
+81 -24
View File
@@ -482,8 +482,8 @@ function showBanner() {
}
// 在显示Banner前,先移除所有已加载的onload-animation类,防止动画重复触发
const animatedElements = document.querySelectorAll('.onload-animation');
animatedElements.forEach(el => {
const animatedElements = document.querySelectorAll<HTMLElement>('.onload-animation');
animatedElements.forEach((el) => {
el.style.animation = 'none';
el.style.opacity = '1';
});
@@ -635,52 +635,109 @@ window.onresize = () => {
import PhotoSwipeLightbox from "photoswipe/lightbox"
import "photoswipe/style.css"
let lightbox: PhotoSwipeLightbox
let pswp = import("photoswipe")
const zoomTargetSelector = ".custom-md img, #post-cover img"
const pswpModule = import("photoswipe")
type PhotoSwipeState = {
lightbox: PhotoSwipeLightbox | null
hookRegistered: boolean
}
const photoSwipeState = (window.__blogPhotoSwipe ??= {
lightbox: null,
hookRegistered: false,
pageLoadRegistered: false,
}) as PhotoSwipeState & { pageLoadRegistered: boolean }
function getZoomTargets() {
return Array.from(document.querySelectorAll<HTMLImageElement>(zoomTargetSelector))
}
function destroyPhotoSwipe() {
photoSwipeState.lightbox?.destroy()
photoSwipeState.lightbox = null
}
function createPhotoSwipe() {
lightbox = new PhotoSwipeLightbox({
gallery: ".custom-md img, #post-cover img",
pswpModule: () => pswp,
const lightbox = new PhotoSwipeLightbox({
gallery: "body",
children: zoomTargetSelector,
pswpModule: () => pswpModule,
closeSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M480-424 284-228q-11 11-28 11t-28-11q-11-11-11-28t11-28l196-196-196-196q-11-11-11-28t11-28q11-11 28-11t28 11l196 196 196-196q11-11 28-11t28 11q11 11 11 28t-11 28L536-480l196 196q11 11 11 28t-11 28q-11 11-28 11t-28-11L480-424Z"/></svg>',
zoomSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M340-540h-40q-17 0-28.5-11.5T260-580q0-17 11.5-28.5T300-620h40v-40q0-17 11.5-28.5T380-700q17 0 28.5 11.5T420-660v40h40q17 0 28.5 11.5T500-580q0 17-11.5 28.5T460-540h-40v40q0 17-11.5 28.5T380-460q-17 0-28.5-11.5T340-500v-40Zm40 220q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l224 224q11 11 11 28t-11 28q-11 11-28 11t-28-11L532-372q-30 24-69 38t-83 14Zm0-80q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>',
padding: { top: 20, bottom: 20, left: 20, right: 20 },
showHideAnimationType: "fade",
showAnimationDuration: 160,
hideAnimationDuration: 140,
wheelToZoom: true,
arrowPrev: false,
arrowNext: false,
imageClickAction: 'close',
tapAction: 'close',
doubleTapAction: 'zoom',
imageClickAction: "close",
tapAction: "close",
doubleTapAction: "zoom",
})
lightbox.addFilter("domItemData", (itemData, element) => {
if (element instanceof HTMLImageElement) {
itemData.src = element.src
const width = element.naturalWidth || element.width || window.innerWidth
const height = element.naturalHeight || element.height || window.innerHeight
const src = element.currentSrc || element.src
itemData.w = Number(element.naturalWidth || window.innerWidth)
itemData.h = Number(element.naturalHeight || window.innerHeight)
itemData.msrc = element.src
itemData.src = src
itemData.w = Number(width)
itemData.h = Number(height)
itemData.msrc = src
}
return itemData
})
lightbox.init()
photoSwipeState.lightbox = lightbox
}
const setup = () => {
window.swup.hooks.on("page:view", () => {
if (lightbox) {
lightbox.destroy()
}
createPhotoSwipe()
function initPhotoSwipe() {
if (photoSwipeState.lightbox || getZoomTargets().length === 0) {
return
}
createPhotoSwipe()
}
function reinitPhotoSwipe() {
destroyPhotoSwipe()
window.requestAnimationFrame(() => {
initPhotoSwipe()
})
}
if (window.swup) {
setup()
function registerPhotoSwipeHook() {
if (photoSwipeState.hookRegistered || !window.swup?.hooks) {
return
}
window.swup.hooks.on("page:view", reinitPhotoSwipe)
photoSwipeState.hookRegistered = true
}
function scheduleInitialPhotoSwipe() {
window.requestAnimationFrame(() => {
initPhotoSwipe()
})
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", scheduleInitialPhotoSwipe, { once: true })
} else {
document.addEventListener("swup:enable", setup)
scheduleInitialPhotoSwipe()
}
if (!photoSwipeState.pageLoadRegistered) {
document.addEventListener("astro:page-load", scheduleInitialPhotoSwipe)
photoSwipeState.pageLoadRegistered = true
}
if (window.swup?.hooks) {
registerPhotoSwipeHook()
} else {
document.addEventListener("swup:enable", registerPhotoSwipeHook, { once: true })
}
</script>