Files
UI/packages/skin/ui/src/watch.ts
T

26 lines
1.4 KiB
TypeScript

/*** 滚动 / 视口监听:根节点被移出文档后自动摘净监听,避免单页应用里反复挂载累积监听 ***/
export function watchViewport(root: HTMLElement, host: HTMLElement | Window, handler: () => void): void {
// —— 状态集中声明 ——
const run = (): void => {
if (!root.isConnected) { // 已卸载:一次性摘掉 scroll 与 resize,后续不再进 handler
host.removeEventListener('scroll', run);
window.removeEventListener('resize', run);
return;
}
handler();
};
host.addEventListener('scroll', run, { passive: true }); // 被动监听:不阻塞滚动
window.addEventListener('resize', run); // 视口变化会改判定线与可滚距离
handler(); // 首帧同步一次:刷新时停在页面中段也能得到正确状态
}
/*** 尺寸监听:根节点尺寸变化时重算(视口缩放、侧栏展开、字体变大),脱离文档即自断,不用手动销毁 ***/
export function trackSize(root: HTMLElement, handler: () => void): void {
if (typeof ResizeObserver === 'undefined') { window.addEventListener('resize', handler); return; } // 老环境回落:至少跟上视口变化
const ro = new ResizeObserver(() => {
if (!root.isConnected) { ro.disconnect(); return; } // 已卸载:断开观察,避免闭包被观察器拽住
handler();
});
ro.observe(root);
}