페이지 전환 깜빡임 완화 및 레이아웃 통합 (v1.10.50)
- 게시물 상세를 default 레이아웃으로 통합해 홈↔게시물 레이아웃 교체 제거 - CSS 전환 베일·스크롤 정리 플러그인으로 이동 중 깜빡임 완화 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
92
app.vue
92
app.vue
@@ -18,68 +18,7 @@ const siteAccentStyle = computed(() => ({
|
||||
'--site-accent': siteAccentColor.value
|
||||
}))
|
||||
|
||||
const isSitePageNavigating = ref(false)
|
||||
|
||||
if (import.meta.client) {
|
||||
const nuxtApp = useNuxtApp()
|
||||
const router = useRouter()
|
||||
|
||||
/** @type {ReturnType<typeof setTimeout> | null} */
|
||||
let hideOverlayTimer = null
|
||||
let navigationOverlayToken = 0
|
||||
|
||||
/**
|
||||
* 공개 페이지 이동 로딩 오버레이를 표시한다.
|
||||
* @returns {void}
|
||||
*/
|
||||
const showSitePageNavigationOverlay = () => {
|
||||
navigationOverlayToken += 1
|
||||
clearTimeout(hideOverlayTimer)
|
||||
hideOverlayTimer = null
|
||||
isSitePageNavigating.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 새 화면이 실제로 그려진 뒤 공개 페이지 이동 로딩 오버레이를 숨긴다.
|
||||
* @returns {void}
|
||||
*/
|
||||
const scheduleHideSitePageNavigationOverlay = () => {
|
||||
const token = navigationOverlayToken
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
hideOverlayTimer = setTimeout(() => {
|
||||
if (token !== navigationOverlayToken) {
|
||||
return
|
||||
}
|
||||
|
||||
isSitePageNavigating.value = false
|
||||
hideOverlayTimer = null
|
||||
}, 120)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 오류·취소 상황에서 공개 페이지 이동 로딩 오버레이를 즉시 숨긴다.
|
||||
* @returns {void}
|
||||
*/
|
||||
const hideSitePageNavigationOverlayImmediately = () => {
|
||||
clearTimeout(hideOverlayTimer)
|
||||
hideOverlayTimer = null
|
||||
isSitePageNavigating.value = false
|
||||
}
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
if (to.fullPath !== from.fullPath) {
|
||||
showSitePageNavigationOverlay()
|
||||
}
|
||||
})
|
||||
router.onError(hideSitePageNavigationOverlayImmediately)
|
||||
nuxtApp.hook('page:loading:start', showSitePageNavigationOverlay)
|
||||
nuxtApp.hook('page:finish', scheduleHideSitePageNavigationOverlay)
|
||||
nuxtApp.hook('app:error', hideSitePageNavigationOverlayImmediately)
|
||||
}
|
||||
const isSitePageNavigating = useState('site-page-veil', () => false)
|
||||
|
||||
useHead(() => ({
|
||||
titleTemplate: (titleChunk) => titleChunk || appSiteSettings.value.title,
|
||||
@@ -97,27 +36,18 @@ useHead(() => ({
|
||||
|
||||
<template>
|
||||
<div class="site-app" :style="siteAccentStyle">
|
||||
<NuxtLoadingIndicator :color="siteAccentColor" :height="3" :throttle="80" :duration="5000" />
|
||||
<Transition
|
||||
enter-active-class="transition duration-100 ease-out"
|
||||
enter-from-class="opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="transition duration-150 ease-in"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
<div
|
||||
v-show="isSitePageNavigating"
|
||||
class="site-page-loading pointer-events-none fixed inset-0 z-[2147483647] grid place-items-center text-[var(--site-text)]"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
aria-busy="true"
|
||||
>
|
||||
<div
|
||||
v-if="isSitePageNavigating"
|
||||
class="site-page-loading fixed inset-0 z-[90] grid place-items-center bg-[var(--site-bg)] text-[var(--site-text)]"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
<div class="site-page-loading__panel grid place-items-center gap-3 text-center">
|
||||
<span class="site-page-loading__spinner size-8 rounded-full border-2 border-[var(--site-line)] border-t-[var(--site-accent)]" aria-hidden="true" />
|
||||
<span class="text-xs font-semibold uppercase tracking-[0.18em] opacity-70">Loading</span>
|
||||
</div>
|
||||
<div class="site-page-loading__panel grid place-items-center gap-3 text-center">
|
||||
<span class="site-page-loading__spinner size-8 rounded-full border-2 border-[var(--site-line)] border-t-[var(--site-accent)]" aria-hidden="true" />
|
||||
<span class="text-xs font-semibold uppercase tracking-[0.18em] opacity-70">Loading</span>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
|
||||
Reference in New Issue
Block a user