mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
优化对话框状态管理
This commit is contained in:
@@ -46,10 +46,10 @@ $header: ".layout-navbar";
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ℹ️ Ensure header styles are preserved when dialog is opened,
|
/* ℹ️ Ensure header styles are preserved when dialog is opened,
|
||||||
regardless of scroll state
|
but only if window was scrolled before dialog opened
|
||||||
*/
|
*/
|
||||||
html.v-overlay-scroll-blocked &.window-scrolled.layout-navbar-fixed,
|
html.v-overlay-scroll-blocked &.window-scrolled.layout-navbar-fixed,
|
||||||
html.dialog-scroll-locked &.layout-navbar-fixed {
|
html.dialog-scroll-locked &.window-scrolled.layout-navbar-fixed {
|
||||||
|
|
||||||
#{$header} {
|
#{$header} {
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
|
|||||||
@@ -17,11 +17,36 @@ export default defineComponent({
|
|||||||
syncRef(isOverlayNavActive, isLayoutOverlayVisible)
|
syncRef(isOverlayNavActive, isLayoutOverlayVisible)
|
||||||
|
|
||||||
const scrollDistance = ref(window.scrollY)
|
const scrollDistance = ref(window.scrollY)
|
||||||
|
const isDialogOpen = ref(false)
|
||||||
|
const wasScrolledBeforeDialog = ref(false)
|
||||||
|
|
||||||
|
// 监听弹窗状态变化
|
||||||
|
const checkDialogState = () => {
|
||||||
|
const wasDialogOpen = isDialogOpen.value
|
||||||
|
isDialogOpen.value =
|
||||||
|
document.documentElement.classList.contains('dialog-scroll-locked') ||
|
||||||
|
document.documentElement.classList.contains('v-overlay-scroll-blocked')
|
||||||
|
|
||||||
|
// 当弹窗刚打开时,记录当前的滚动状态
|
||||||
|
if (!wasDialogOpen && isDialogOpen.value) {
|
||||||
|
wasScrolledBeforeDialog.value = scrollDistance.value > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.addEventListener('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
scrollDistance.value = window.scrollY
|
scrollDistance.value = window.scrollY
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 初始检查弹窗状态
|
||||||
|
checkDialogState()
|
||||||
|
|
||||||
|
// 监听 DOM 变化以检测弹窗状态
|
||||||
|
const observer = new MutationObserver(checkDialogState)
|
||||||
|
observer.observe(document.documentElement, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['class'],
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@@ -88,9 +113,6 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 检查是否有弹窗打开(通过CSS类名判断)
|
|
||||||
const isDialogOpen = document.documentElement.classList.contains('dialog-scroll-locked')
|
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
'div',
|
'div',
|
||||||
{
|
{
|
||||||
@@ -99,7 +121,7 @@ export default defineComponent({
|
|||||||
'layout-navbar-fixed',
|
'layout-navbar-fixed',
|
||||||
mdAndDown.value && 'layout-overlay-nav',
|
mdAndDown.value && 'layout-overlay-nav',
|
||||||
route.meta.layoutWrapperClasses,
|
route.meta.layoutWrapperClasses,
|
||||||
(scrollDistance.value || isDialogOpen) && 'window-scrolled',
|
(scrollDistance.value > 0 || (isDialogOpen.value && wasScrolledBeforeDialog.value)) && 'window-scrolled',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
[verticalNav, h('div', { class: 'layout-content-wrapper' }, [navbar, main, footer]), layoutOverlay],
|
[verticalNav, h('div', { class: 'layout-content-wrapper' }, [navbar, main, footer]), layoutOverlay],
|
||||||
|
|||||||
@@ -3,38 +3,6 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
// 基础样式
|
|
||||||
html.v-overlay-scroll-blocked {
|
|
||||||
position: fixed;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
--v-body-scroll-y: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
overscroll-behavior: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 防止弹窗滚动穿透
|
|
||||||
.v-dialog {
|
|
||||||
.v-overlay__content {
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-card {
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
touch-action: pan-y;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-card-text {
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 防止滚动穿透的通用样式
|
|
||||||
.v-overlay--active {
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin hide-scrollbar {
|
@mixin hide-scrollbar {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user