fix(首页): 修复入场动画期间滚动锁定问题

确保在 Lenis 加载完成前后都能正确锁定页面滚动
修复滚动锁定计数逻辑,避免重复操作
This commit is contained in:
2026-04-27 02:42:03 +08:00
parent 226dc5c147
commit ea9b7747e2
3 changed files with 21 additions and 7 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
/* 首页入场动画期间首帧就隐藏滚动条,避免黑色遮罩边缘露出白色滚动槽。 */ /* 首页入场动画期间首帧就隐藏滚动条,避免黑色遮罩边缘露出白色滚动槽。 */
html.is-home-intro-active, html.is-home-intro-active,
html.is-home-intro-active body { html.is-home-intro-active body {
overflow: hidden; overflow: hidden !important;
background: #000; background: #000;
} }
} }
+11 -5
View File
@@ -11,7 +11,7 @@ export const usePageScrollLock = (isLocked: Ref<boolean> | boolean) => {
// SSR 和 CSR 都支持:自动将 class 注入到 HTML 标签上 // SSR 和 CSR 都支持:自动将 class 注入到 HTML 标签上
useHead({ useHead({
htmlAttrs: { htmlAttrs: {
class: computed(() => unref(isLocked) ? 'is-home-intro-active' : undefined) class: computed(() => unref(isLocked) ? 'is-home-intro-active' : '')
} }
}) })
@@ -23,19 +23,25 @@ export const usePageScrollLock = (isLocked: Ref<boolean> | boolean) => {
currentlyLocked = locked currentlyLocked = locked
// Lenis 控制仅在客户端有效 // Lenis 控制仅在客户端有效
if (import.meta.client && $lenis) { if (import.meta.client) {
if (locked) { if (locked) {
lenisLockCount++ lenisLockCount++
// 只有第一个锁请求时,才真正停止 Lenis 并滚动到顶部 // 只有第一个锁请求时,才真正停止 Lenis 并滚动到顶部
if (lenisLockCount === 1) { if (lenisLockCount === 1) {
$lenis.scrollTo(0, { immediate: true }) document.documentElement.classList.add('is-home-intro-active')
$lenis.stop() if ($lenis) {
$lenis.scrollTo(0, { immediate: true })
$lenis.stop()
}
} }
} else { } else {
lenisLockCount = Math.max(0, lenisLockCount - 1) lenisLockCount = Math.max(0, lenisLockCount - 1)
// 只有当所有锁请求都释放时,才重新启动 Lenis // 只有当所有锁请求都释放时,才重新启动 Lenis
if (lenisLockCount === 0) { if (lenisLockCount === 0) {
$lenis.start() document.documentElement.classList.remove('is-home-intro-active')
if ($lenis) {
$lenis.start()
}
} }
} }
} }
+8
View File
@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useHead, useSeoMeta } from '#imports'
import { useUserStore } from '~/stores/user' import { useUserStore } from '~/stores/user'
import { useAppStore } from '~/stores/app' import { useAppStore } from '~/stores/app'
import { usePageScrollLock } from '~/composables/usePageScrollLock' import { usePageScrollLock } from '~/composables/usePageScrollLock'
@@ -20,6 +21,13 @@ if (!userStore.isLoggedIn) {
userStore.loadDemoUser() userStore.loadDemoUser()
} }
// 保证即使 Lenis 还没加载完成,也能通过原生 CSS 锁定页面
useHead({
htmlAttrs: {
class: computed(() => (isIntroActive.value ? 'is-home-intro-active' : '')),
},
})
// 使用组合式函数管理 Lenis 滚动锁定 // 使用组合式函数管理 Lenis 滚动锁定
usePageScrollLock(isIntroActive) usePageScrollLock(isIntroActive)