2024-08-02 18:19:39 +08:00
|
|
|
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
2024-01-29 09:26:07 +08:00
|
|
|
let lockCount = 0;
|
|
|
|
let originalMarginRight = '';
|
|
|
|
let originalOverflow = '';
|
|
|
|
let originalOverflowX = '';
|
|
|
|
let originalOverflowY = '';
|
|
|
|
export const lockHtmlScrollRightCompensationRef = ref('0px');
|
|
|
|
export function useLockHtmlScroll(lockRef) {
|
|
|
|
// not browser
|
|
|
|
if (typeof document === 'undefined') return;
|
|
|
|
const el = document.documentElement;
|
|
|
|
let watchStopHandle;
|
|
|
|
let activated = false;
|
|
|
|
const unlock = () => {
|
|
|
|
el.style.marginRight = originalMarginRight;
|
|
|
|
el.style.overflow = originalOverflow;
|
|
|
|
el.style.overflowX = originalOverflowX;
|
|
|
|
el.style.overflowY = originalOverflowY;
|
|
|
|
lockHtmlScrollRightCompensationRef.value = '0px';
|
|
|
|
};
|
|
|
|
onMounted(() => {
|
|
|
|
watchStopHandle = watch(lockRef, value => {
|
|
|
|
if (value) {
|
|
|
|
if (!lockCount) {
|
|
|
|
const scrollbarWidth = window.innerWidth - el.offsetWidth;
|
|
|
|
if (scrollbarWidth > 0) {
|
|
|
|
originalMarginRight = el.style.marginRight;
|
|
|
|
el.style.marginRight = `${scrollbarWidth}px`;
|
|
|
|
lockHtmlScrollRightCompensationRef.value = `${scrollbarWidth}px`;
|
|
|
|
}
|
|
|
|
originalOverflow = el.style.overflow;
|
|
|
|
originalOverflowX = el.style.overflowX;
|
|
|
|
originalOverflowY = el.style.overflowY;
|
|
|
|
el.style.overflow = 'hidden';
|
|
|
|
el.style.overflowX = 'hidden';
|
|
|
|
el.style.overflowY = 'hidden';
|
|
|
|
}
|
|
|
|
activated = true;
|
|
|
|
lockCount++;
|
|
|
|
} else {
|
|
|
|
lockCount--;
|
|
|
|
if (!lockCount) {
|
|
|
|
unlock();
|
|
|
|
}
|
|
|
|
activated = false;
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
immediate: true
|
|
|
|
});
|
|
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
watchStopHandle === null || watchStopHandle === void 0 ? void 0 : watchStopHandle();
|
|
|
|
if (activated) {
|
|
|
|
lockCount--;
|
|
|
|
if (!lockCount) {
|
|
|
|
unlock();
|
|
|
|
}
|
|
|
|
activated = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|