/** 主布局内容区:滚动层 + 全屏详情弹窗遮罩层(方案 A,二者为兄弟节点) */ let layoutContentScrollEl: HTMLElement | null = null; let layoutContentModalMountEl: HTMLElement | null = null; export const LAYOUT_CONTENT_SCROLL_LOCK_CLASS = "layoutShell__contentScroll_scrollLocked"; let layoutContentScrollLockCount = 0; export function setLayoutContentScrollRoot(el: HTMLElement | null): void { layoutContentScrollEl = el; } export function getLayoutContentScrollRoot(): HTMLElement | null { return layoutContentScrollEl; } export function setLayoutContentModalMount(el: HTMLElement | null): void { layoutContentModalMountEl = el; } export function getLayoutContentModalMount(): HTMLElement | null { return layoutContentModalMountEl; } /** 全屏详情弹窗打开时锁住背后滚动层(保留 scrollTop,仅禁止滚动) */ export function lockLayoutContentScroll(): void { layoutContentScrollLockCount += 1; layoutContentScrollEl?.classList.add(LAYOUT_CONTENT_SCROLL_LOCK_CLASS); } export function unlockLayoutContentScroll(): void { layoutContentScrollLockCount = Math.max(0, layoutContentScrollLockCount - 1); if (layoutContentScrollLockCount === 0) { layoutContentScrollEl?.classList.remove(LAYOUT_CONTENT_SCROLL_LOCK_CLASS); } } export function isLayoutContentScrollLocked(): boolean { return layoutContentScrollLockCount > 0; } /** 滚动事件是否来自弹窗遮罩层(应忽略,避免误触发 composer 收起) */ export function isScrollEventFromLayoutModalMount(target: EventTarget | null): boolean { if (layoutContentModalMountEl == null || target == null) return false; return layoutContentModalMountEl.contains(target as Node); } /** 滚动是否发生在内容滚动层及其子树内 */ export function isScrollEventInLayoutContentScroll(target: EventTarget | null): boolean { if (layoutContentScrollEl == null || !(target instanceof HTMLElement)) return false; return target === layoutContentScrollEl || layoutContentScrollEl.contains(target); }