Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tua-body-scroll-lock

Package Overview
Dependencies
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tua-body-scroll-lock - npm Package Compare versions

Comparing version 1.5.0 to 1.5.1-beta.1

dist/methods.d.ts

5

dist/getLockState.d.ts
import type { BSLOptions, LockState } from './types';
/**
* get current lockState
* @param options
* @returns lockState
*/
export declare function getLockState(options?: BSLOptions): LockState;

@@ -3,0 +8,0 @@ export declare namespace getLockState {

7

dist/index.d.ts

@@ -1,6 +0,3 @@

import type { BSLOptions, Nullable } from './types';
declare function lock(targetElement?: Nullable<HTMLElement>, options?: BSLOptions): void;
declare function unlock(targetElement?: Nullable<HTMLElement>, options?: BSLOptions): void;
declare function clearBodyLocks(options?: BSLOptions): void;
export * from './types';
export { lock, unlock, clearBodyLocks };
export * from './getLockState';
export { lock, unlock, clearBodyLocks } from './methods';
/**
* tua-body-scroll-lock v1.5.0
* tua-body-scroll-lock v1.5.1-beta.1
* (c) 2024 Evinma, BuptStEve

@@ -70,2 +70,7 @@ * @license MIT

}
function toArray(x) {
if (!x)
return [];
return Array.isArray(x) ? x : [x];
}

@@ -82,2 +87,7 @@ const initialLockState = {

};
/**
* get current lockState
* @param options
* @returns lockState
*/
function getLockState(options) {

@@ -160,3 +170,7 @@ if (isServer())

const eventListenerOptions = getEventListenerOptions({ passive: false });
/**
* lock body scroll
* @param targetElement the element(s) still needs scrolling(iOS only)
* @param options
*/
function lock(targetElement, options) {

@@ -166,29 +180,21 @@ if (isServer())

noticeRequiredTargetElement(targetElement);
const detectRes = detectOS();
const lockState = getLockState(options);
if (detectOS().ios) {
// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement];
elementArray.forEach((element) => {
if (element && lockState.lockedElements.indexOf(element) === -1) {
element.ontouchstart = (event) => {
const { clientX, clientY } = event.targetTouches[0];
lockState.initialClientPos = { clientX, clientY };
};
element.ontouchmove = (event) => {
if (event.targetTouches.length !== 1)
return;
handleScroll(event, element, lockState.initialClientPos);
};
lockState.lockedElements.push(element);
}
});
}
if (!lockState.documentListenerAdded) {
document.addEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = true;
}
if (detectRes.ios) {
toArray(targetElement)
.filter(e => lockState.lockedElements.indexOf(e) === -1)
.forEach((element) => {
element.ontouchstart = (event) => {
const { clientX, clientY } = event.targetTouches[0];
lockState.initialClientPos = { clientX, clientY };
};
element.ontouchmove = (event) => {
handleScroll(event, element, lockState.initialClientPos);
};
lockState.lockedElements.push(element);
});
addTouchMoveListener(lockState);
}
else if (lockState.lockedNum <= 0) {
lockState.unLockCallback = detectOS().android
lockState.unLockCallback = detectRes.android
? setOverflowHiddenMobile(options)

@@ -199,2 +205,7 @@ : setOverflowHiddenPc();

}
/**
* unlock body scroll
* @param targetElement the element(s) still needs scrolling(iOS only)
* @param options
*/
function unlock(targetElement, options) {

@@ -208,24 +219,18 @@ if (isServer())

return;
if (!detectOS().ios &&
typeof lockState.unLockCallback === 'function') {
lockState.unLockCallback();
if (unlockByCallback(lockState))
return;
}
// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement];
elementArray.forEach((element) => {
const index = lockState.lockedElements.indexOf(element);
if (index !== -1) {
element.ontouchmove = null;
element.ontouchstart = null;
lockState.lockedElements.splice(index, 1);
}
});
}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = false;
}
toArray(targetElement).forEach((element) => {
const index = lockState.lockedElements.indexOf(element);
if (index !== -1) {
element.ontouchmove = null;
element.ontouchstart = null;
lockState.lockedElements.splice(index, 1);
}
});
removeTouchMoveListener(lockState);
}
/**
* clear all body locks
* @param options
*/
function clearBodyLocks(options) {

@@ -236,10 +241,5 @@ if (isServer())

lockState.lockedNum = 0;
if (!detectOS().ios &&
typeof lockState.unLockCallback === 'function') {
lockState.unLockCallback();
if (unlockByCallback(lockState))
return;
}
// iOS
if (lockState.lockedElements.length) {
// clear events
let element = lockState.lockedElements.pop();

@@ -252,8 +252,27 @@ while (element) {

}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = false;
}
removeTouchMoveListener(lockState);
}
function unlockByCallback(lockState) {
if (detectOS().ios)
return false;
if (typeof lockState.unLockCallback !== 'function')
return false;
lockState.unLockCallback();
return true;
}
function addTouchMoveListener(lockState) {
if (!detectOS().ios)
return;
if (lockState.documentListenerAdded)
return;
document.addEventListener('touchmove', getPreventEventDefault(), getEventListenerOptions({ passive: false }));
lockState.documentListenerAdded = true;
}
function removeTouchMoveListener(lockState) {
if (!lockState.documentListenerAdded)
return;
document.removeEventListener('touchmove', getPreventEventDefault(), getEventListenerOptions({ passive: false }));
lockState.documentListenerAdded = false;
}
export { clearBodyLocks, lock, unlock };
export { clearBodyLocks, getLockState, lock, unlock };
/**
* tua-body-scroll-lock v1.5.0
* tua-body-scroll-lock v1.5.1-beta.1
* (c) 2024 Evinma, BuptStEve
* @license MIT
*/
const e=()=>"undefined"==typeof window,t=e=>{e=e||navigator.userAgent;const t=/(iPad).*OS\s([\d_]+)/.test(e);return{ios:!t&&/(iPhone\sOS)\s([\d_]+)/.test(e)||t,android:/(Android);?[\s/]+([\d.]+)?/.test(e)}};function o(){return"__BSL_PREVENT_DEFAULT__"in window||(window.__BSL_PREVENT_DEFAULT__=function(e){e.cancelable&&e.preventDefault()}),window.__BSL_PREVENT_DEFAULT__}const n={lockedNum:0,lockedElements:[],unLockCallback:null,documentListenerAdded:!1,initialClientPos:{clientX:0,clientY:0}};function i(t){if(e())return n;if(!(null==t?void 0:t.useGlobalLockState))return i.lockState;const o="__BSL_LOCK_STATE__"in window?Object.assign(Object.assign({},n),window.__BSL_LOCK_STATE__):n;return window.__BSL_LOCK_STATE__=o,o}i.lockState=n;const l=function(t){if(e())return!1;if(!t)throw new Error("options must be provided");let o=!1;const n={get passive(){o=!0}},i=()=>{},l="__TUA_BSL_TEST_PASSIVE__";window.addEventListener(l,i,n),window.removeEventListener(l,i,n);const{capture:c}=t;return o?t:void 0!==c&&c}({passive:!1});function c(n,c){if(e())return;const s=i(c);if(t().ios){if(n){(Array.isArray(n)?n:[n]).forEach((e=>{e&&-1===s.lockedElements.indexOf(e)&&(e.ontouchstart=e=>{const{clientX:t,clientY:o}=e.targetTouches[0];s.initialClientPos={clientX:t,clientY:o}},e.ontouchmove=t=>{1===t.targetTouches.length&&function(e,t,n){if(t){const{scrollTop:i,scrollLeft:l,scrollWidth:c,scrollHeight:s,clientWidth:d,clientHeight:r}=t,u=e.targetTouches[0].clientX-n.clientX,a=e.targetTouches[0].clientY-n.clientY,f=Math.abs(a)>Math.abs(u);if(f&&(a>0&&0===i||a<0&&i+r+1>=s)||!f&&(u>0&&0===l||u<0&&l+d+1>=c))return o()(e)}e.stopPropagation()}(t,e,s.initialClientPos)},s.lockedElements.push(e))}))}s.documentListenerAdded||(document.addEventListener("touchmove",o(),l),s.documentListenerAdded=!0)}else s.lockedNum<=0&&(s.unLockCallback=t().android?function(e){const t=document.documentElement,o=document.body,n=t.scrollTop||o.scrollTop,i=Object.assign({},t.style),l=Object.assign({},o.style);return t.style.height="100%",t.style.overflow="hidden",o.style.top=`-${n}px`,o.style.width="100%",o.style.height="auto",o.style.position="fixed",o.style.overflow=(null==e?void 0:e.overflowType)||"hidden",()=>{t.style.height=i.height||"",t.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach((e=>{o.style[e]=l[e]||""})),"scrollBehavior"in document.documentElement.style?window.scrollTo({top:n,behavior:"instant"}):window.scrollTo(0,n)}}(c):function(){const e=document.documentElement,t=Object.assign({},e.style),o=window.innerWidth-e.clientWidth,n=parseInt(window.getComputedStyle(e).paddingRight,10);return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight=`${o+n}px`,()=>{["overflow","boxSizing","paddingRight"].forEach((o=>{e.style[o]=t[o]||""}))}}());s.lockedNum+=1}function s(n,c){if(e())return;const s=i(c);if(s.lockedNum-=1,!(s.lockedNum>0))if(t().ios||"function"!=typeof s.unLockCallback){if(n){(Array.isArray(n)?n:[n]).forEach((e=>{const t=s.lockedElements.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,s.lockedElements.splice(t,1))}))}s.documentListenerAdded&&(document.removeEventListener("touchmove",o(),l),s.documentListenerAdded=!1)}else s.unLockCallback()}function d(n){if(e())return;const c=i(n);if(c.lockedNum=0,t().ios||"function"!=typeof c.unLockCallback){if(c.lockedElements.length){let e=c.lockedElements.pop();for(;e;)e.ontouchmove=null,e.ontouchstart=null,e=c.lockedElements.pop()}c.documentListenerAdded&&(document.removeEventListener("touchmove",o(),l),c.documentListenerAdded=!1)}else c.unLockCallback()}export{d as clearBodyLocks,c as lock,s as unlock};
const e=()=>"undefined"==typeof window,t=e=>{e=e||navigator.userAgent;const t=/(iPad).*OS\s([\d_]+)/.test(e);return{ios:!t&&/(iPhone\sOS)\s([\d_]+)/.test(e)||t,android:/(Android);?[\s/]+([\d.]+)?/.test(e)}};function n(t){if(e())return!1;if(!t)throw new Error("options must be provided");let n=!1;const o={get passive(){n=!0}},i=()=>{},l="__TUA_BSL_TEST_PASSIVE__";window.addEventListener(l,i,o),window.removeEventListener(l,i,o);const{capture:c}=t;return n?t:void 0!==c&&c}function o(){return"__BSL_PREVENT_DEFAULT__"in window||(window.__BSL_PREVENT_DEFAULT__=function(e){e.cancelable&&e.preventDefault()}),window.__BSL_PREVENT_DEFAULT__}function i(e){return e?Array.isArray(e)?e:[e]:[]}const l={lockedNum:0,lockedElements:[],unLockCallback:null,documentListenerAdded:!1,initialClientPos:{clientX:0,clientY:0}};function c(t){if(e())return l;if(!(null==t?void 0:t.useGlobalLockState))return c.lockState;const n="__BSL_LOCK_STATE__"in window?Object.assign(Object.assign({},l),window.__BSL_LOCK_STATE__):l;return window.__BSL_LOCK_STATE__=n,n}function s(l,s){if(e())return;const d=t(),r=c(s);d.ios?(i(l).filter((e=>-1===r.lockedElements.indexOf(e))).forEach((e=>{e.ontouchstart=e=>{const{clientX:t,clientY:n}=e.targetTouches[0];r.initialClientPos={clientX:t,clientY:n}},e.ontouchmove=t=>{!function(e,t,n){if(t){const{scrollTop:i,scrollLeft:l,scrollWidth:c,scrollHeight:s,clientWidth:d,clientHeight:r}=t,u=e.targetTouches[0].clientX-n.clientX,a=e.targetTouches[0].clientY-n.clientY,f=Math.abs(a)>Math.abs(u);if(f&&(a>0&&0===i||a<0&&i+r+1>=s)||!f&&(u>0&&0===l||u<0&&l+d+1>=c))return o()(e)}e.stopPropagation()}(t,e,r.initialClientPos)},r.lockedElements.push(e)})),function(e){if(!t().ios)return;if(e.documentListenerAdded)return;document.addEventListener("touchmove",o(),n({passive:!1})),e.documentListenerAdded=!0}(r)):r.lockedNum<=0&&(r.unLockCallback=d.android?function(e){const t=document.documentElement,n=document.body,o=t.scrollTop||n.scrollTop,i=Object.assign({},t.style),l=Object.assign({},n.style);return t.style.height="100%",t.style.overflow="hidden",n.style.top=`-${o}px`,n.style.width="100%",n.style.height="auto",n.style.position="fixed",n.style.overflow=(null==e?void 0:e.overflowType)||"hidden",()=>{t.style.height=i.height||"",t.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach((e=>{n.style[e]=l[e]||""})),"scrollBehavior"in document.documentElement.style?window.scrollTo({top:o,behavior:"instant"}):window.scrollTo(0,o)}}(s):function(){const e=document.documentElement,t=Object.assign({},e.style),n=window.innerWidth-e.clientWidth,o=parseInt(window.getComputedStyle(e).paddingRight,10);return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight=`${n+o}px`,()=>{["overflow","boxSizing","paddingRight"].forEach((n=>{e.style[n]=t[n]||""}))}}()),r.lockedNum+=1}function d(t,n){if(e())return;const o=c(n);o.lockedNum-=1,o.lockedNum>0||u(o)||(i(t).forEach((e=>{const t=o.lockedElements.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,o.lockedElements.splice(t,1))})),a(o))}function r(t){if(e())return;const n=c(t);if(n.lockedNum=0,!u(n)){if(n.lockedElements.length){let e=n.lockedElements.pop();for(;e;)e.ontouchmove=null,e.ontouchstart=null,e=n.lockedElements.pop()}a(n)}}function u(e){return!t().ios&&("function"==typeof e.unLockCallback&&(e.unLockCallback(),!0))}function a(e){e.documentListenerAdded&&(document.removeEventListener("touchmove",o(),n({passive:!1})),e.documentListenerAdded=!1)}c.lockState=l;export{r as clearBodyLocks,c as getLockState,s as lock,d as unlock};
/**
* tua-body-scroll-lock v1.5.0
* tua-body-scroll-lock v1.5.1-beta.1
* (c) 2024 Evinma, BuptStEve

@@ -72,2 +72,6 @@ * @license MIT

}
function toArray(x) {
if (!x) return [];
return Array.isArray(x) ? x : [x];
}

@@ -84,2 +88,7 @@ var initialLockState = {

};
/**
* get current lockState
* @param options
* @returns lockState
*/
function getLockState(options) {

@@ -165,41 +174,41 @@ if (isServer()) return initialLockState;

var eventListenerOptions = getEventListenerOptions({
passive: false
});
/**
* lock body scroll
* @param targetElement the element(s) still needs scrolling(iOS only)
* @param options
*/
function lock(targetElement, options) {
if (isServer()) return;
noticeRequiredTargetElement(targetElement);
var detectRes = detectOS();
var lockState = getLockState(options);
if (detectOS().ios) {
// iOS
if (targetElement) {
var elementArray = Array.isArray(targetElement) ? targetElement : [targetElement];
elementArray.forEach(function (element) {
if (element && lockState.lockedElements.indexOf(element) === -1) {
element.ontouchstart = function (event) {
var _event$targetTouches$ = event.targetTouches[0],
clientX = _event$targetTouches$.clientX,
clientY = _event$targetTouches$.clientY;
lockState.initialClientPos = {
clientX: clientX,
clientY: clientY
};
};
element.ontouchmove = function (event) {
if (event.targetTouches.length !== 1) return;
handleScroll(event, element, lockState.initialClientPos);
};
lockState.lockedElements.push(element);
}
});
}
if (!lockState.documentListenerAdded) {
document.addEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = true;
}
if (detectRes.ios) {
toArray(targetElement).filter(function (e) {
return lockState.lockedElements.indexOf(e) === -1;
}).forEach(function (element) {
element.ontouchstart = function (event) {
var _event$targetTouches$ = event.targetTouches[0],
clientX = _event$targetTouches$.clientX,
clientY = _event$targetTouches$.clientY;
lockState.initialClientPos = {
clientX: clientX,
clientY: clientY
};
};
element.ontouchmove = function (event) {
handleScroll(event, element, lockState.initialClientPos);
};
lockState.lockedElements.push(element);
});
addTouchMoveListener(lockState);
} else if (lockState.lockedNum <= 0) {
lockState.unLockCallback = detectOS().android ? setOverflowHiddenMobile(options) : setOverflowHiddenPc();
lockState.unLockCallback = detectRes.android ? setOverflowHiddenMobile(options) : setOverflowHiddenPc();
}
lockState.lockedNum += 1;
}
/**
* unlock body scroll
* @param targetElement the element(s) still needs scrolling(iOS only)
* @param options
*/
function unlock(targetElement, options) {

@@ -211,23 +220,17 @@ if (isServer()) return;

if (lockState.lockedNum > 0) return;
if (!detectOS().ios && typeof lockState.unLockCallback === 'function') {
lockState.unLockCallback();
return;
}
// iOS
if (targetElement) {
var elementArray = Array.isArray(targetElement) ? targetElement : [targetElement];
elementArray.forEach(function (element) {
var index = lockState.lockedElements.indexOf(element);
if (index !== -1) {
element.ontouchmove = null;
element.ontouchstart = null;
lockState.lockedElements.splice(index, 1);
}
});
}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = false;
}
if (unlockByCallback(lockState)) return;
toArray(targetElement).forEach(function (element) {
var index = lockState.lockedElements.indexOf(element);
if (index !== -1) {
element.ontouchmove = null;
element.ontouchstart = null;
lockState.lockedElements.splice(index, 1);
}
});
removeTouchMoveListener(lockState);
}
/**
* clear all body locks
* @param options
*/
function clearBodyLocks(options) {

@@ -237,9 +240,4 @@ if (isServer()) return;

lockState.lockedNum = 0;
if (!detectOS().ios && typeof lockState.unLockCallback === 'function') {
lockState.unLockCallback();
return;
}
// iOS
if (unlockByCallback(lockState)) return;
if (lockState.lockedElements.length) {
// clear events
var element = lockState.lockedElements.pop();

@@ -252,9 +250,28 @@ while (element) {

}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions);
lockState.documentListenerAdded = false;
}
removeTouchMoveListener(lockState);
}
function unlockByCallback(lockState) {
if (detectOS().ios) return false;
if (typeof lockState.unLockCallback !== 'function') return false;
lockState.unLockCallback();
return true;
}
function addTouchMoveListener(lockState) {
if (!detectOS().ios) return;
if (lockState.documentListenerAdded) return;
document.addEventListener('touchmove', getPreventEventDefault(), getEventListenerOptions({
passive: false
}));
lockState.documentListenerAdded = true;
}
function removeTouchMoveListener(lockState) {
if (!lockState.documentListenerAdded) return;
document.removeEventListener('touchmove', getPreventEventDefault(), getEventListenerOptions({
passive: false
}));
lockState.documentListenerAdded = false;
}
exports.clearBodyLocks = clearBodyLocks;
exports.getLockState = getLockState;
exports.lock = lock;

@@ -261,0 +278,0 @@ exports.unlock = unlock;

/**
* tua-body-scroll-lock v1.5.0
* tua-body-scroll-lock v1.5.1-beta.1
* (c) 2024 Evinma, BuptStEve
* @license MIT
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).bodyScrollLock={})}(this,(function(e){"use strict";var t=function(){return"undefined"==typeof window},n=function(e){e=e||navigator.userAgent;var t=/(iPad).*OS\s([\d_]+)/.test(e);return{ios:!t&&/(iPhone\sOS)\s([\d_]+)/.test(e)||t,android:/(Android);?[\s/]+([\d.]+)?/.test(e)}};function o(){return"__BSL_PREVENT_DEFAULT__"in window||(window.__BSL_PREVENT_DEFAULT__=function(e){e.cancelable&&e.preventDefault()}),window.__BSL_PREVENT_DEFAULT__}var i={lockedNum:0,lockedElements:[],unLockCallback:null,documentListenerAdded:!1,initialClientPos:{clientX:0,clientY:0}};function l(e){if(t())return i;if(!(null==e?void 0:e.useGlobalLockState))return l.lockState;var n="__BSL_LOCK_STATE__"in window?Object.assign(Object.assign({},i),window.__BSL_LOCK_STATE__):i;return window.__BSL_LOCK_STATE__=n,n}l.lockState=i;var c=function(e){if(t())return!1;if(!e)throw new Error("options must be provided");var n=!1,o={get passive(){n=!0}},i=function(){},l="__TUA_BSL_TEST_PASSIVE__";window.addEventListener(l,i,o),window.removeEventListener(l,i,o);var c=e.capture;return n?e:void 0!==c&&c}({passive:!1});e.clearBodyLocks=function(e){if(!t()){var i=l(e);if(i.lockedNum=0,n().ios||"function"!=typeof i.unLockCallback){if(i.lockedElements.length)for(var d=i.lockedElements.pop();d;)d.ontouchmove=null,d.ontouchstart=null,d=i.lockedElements.pop();i.documentListenerAdded&&(document.removeEventListener("touchmove",o(),c),i.documentListenerAdded=!1)}else i.unLockCallback()}},e.lock=function(e,i){if(!t()){var d,r,s,u,a=l(i);if(n().ios){if(e)(Array.isArray(e)?e:[e]).forEach((function(e){e&&-1===a.lockedElements.indexOf(e)&&(e.ontouchstart=function(e){var t=e.targetTouches[0],n=t.clientX,o=t.clientY;a.initialClientPos={clientX:n,clientY:o}},e.ontouchmove=function(t){1===t.targetTouches.length&&function(e,t,n){if(t){var i=t.scrollTop,l=t.scrollLeft,c=t.scrollWidth,d=t.scrollHeight,r=t.clientWidth,s=t.clientHeight,u=e.targetTouches[0].clientX-n.clientX,a=e.targetTouches[0].clientY-n.clientY,f=Math.abs(a)>Math.abs(u);if(f&&(a>0&&0===i||a<0&&i+s+1>=d)||!f&&(u>0&&0===l||u<0&&l+r+1>=c))return o()(e)}e.stopPropagation()}(t,e,a.initialClientPos)},a.lockedElements.push(e))}));a.documentListenerAdded||(document.addEventListener("touchmove",o(),c),a.documentListenerAdded=!0)}else a.lockedNum<=0&&(a.unLockCallback=n().android?function(e){var t=document.documentElement,n=document.body,o=t.scrollTop||n.scrollTop,i=Object.assign({},t.style),l=Object.assign({},n.style);return t.style.height="100%",t.style.overflow="hidden",n.style.top="-".concat(o,"px"),n.style.width="100%",n.style.height="auto",n.style.position="fixed",n.style.overflow=(null==e?void 0:e.overflowType)||"hidden",function(){t.style.height=i.height||"",t.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach((function(e){n.style[e]=l[e]||""})),"scrollBehavior"in document.documentElement.style?window.scrollTo({top:o,behavior:"instant"}):window.scrollTo(0,o)}}(i):(d=document.documentElement,r=Object.assign({},d.style),s=window.innerWidth-d.clientWidth,u=parseInt(window.getComputedStyle(d).paddingRight,10),d.style.overflow="hidden",d.style.boxSizing="border-box",d.style.paddingRight="".concat(s+u,"px"),function(){["overflow","boxSizing","paddingRight"].forEach((function(e){d.style[e]=r[e]||""}))}));a.lockedNum+=1}},e.unlock=function(e,i){if(!t()){var d=l(i);if(d.lockedNum-=1,!(d.lockedNum>0))if(n().ios||"function"!=typeof d.unLockCallback){if(e)(Array.isArray(e)?e:[e]).forEach((function(e){var t=d.lockedElements.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,d.lockedElements.splice(t,1))}));d.documentListenerAdded&&(document.removeEventListener("touchmove",o(),c),d.documentListenerAdded=!1)}else d.unLockCallback()}}}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).bodyScrollLock={})}(this,(function(e){"use strict";var t=function(){return"undefined"==typeof window},n=function(e){e=e||navigator.userAgent;var t=/(iPad).*OS\s([\d_]+)/.test(e);return{ios:!t&&/(iPhone\sOS)\s([\d_]+)/.test(e)||t,android:/(Android);?[\s/]+([\d.]+)?/.test(e)}};function o(e){if(t())return!1;if(!e)throw new Error("options must be provided");var n=!1,o={get passive(){n=!0}},i=function(){},l="__TUA_BSL_TEST_PASSIVE__";window.addEventListener(l,i,o),window.removeEventListener(l,i,o);var c=e.capture;return n?e:void 0!==c&&c}function i(){return"__BSL_PREVENT_DEFAULT__"in window||(window.__BSL_PREVENT_DEFAULT__=function(e){e.cancelable&&e.preventDefault()}),window.__BSL_PREVENT_DEFAULT__}function l(e){return e?Array.isArray(e)?e:[e]:[]}var c={lockedNum:0,lockedElements:[],unLockCallback:null,documentListenerAdded:!1,initialClientPos:{clientX:0,clientY:0}};function r(e){if(t())return c;if(!(null==e?void 0:e.useGlobalLockState))return r.lockState;var n="__BSL_LOCK_STATE__"in window?Object.assign(Object.assign({},c),window.__BSL_LOCK_STATE__):c;return window.__BSL_LOCK_STATE__=n,n}function d(e){return!n().ios&&("function"==typeof e.unLockCallback&&(e.unLockCallback(),!0))}function s(e){e.documentListenerAdded&&(document.removeEventListener("touchmove",i(),o({passive:!1})),e.documentListenerAdded=!1)}r.lockState=c,e.clearBodyLocks=function(e){if(!t()){var n=r(e);if(n.lockedNum=0,!d(n)){if(n.lockedElements.length)for(var o=n.lockedElements.pop();o;)o.ontouchmove=null,o.ontouchstart=null,o=n.lockedElements.pop();s(n)}}},e.getLockState=r,e.lock=function(e,c){if(!t()){var d,s,u,a,f=n(),h=r(c);f.ios?(l(e).filter((function(e){return-1===h.lockedElements.indexOf(e)})).forEach((function(e){e.ontouchstart=function(e){var t=e.targetTouches[0],n=t.clientX,o=t.clientY;h.initialClientPos={clientX:n,clientY:o}},e.ontouchmove=function(t){!function(e,t,n){if(t){var o=t.scrollTop,l=t.scrollLeft,c=t.scrollWidth,r=t.scrollHeight,d=t.clientWidth,s=t.clientHeight,u=e.targetTouches[0].clientX-n.clientX,a=e.targetTouches[0].clientY-n.clientY,f=Math.abs(a)>Math.abs(u);if(f&&(a>0&&0===o||a<0&&o+s+1>=r)||!f&&(u>0&&0===l||u<0&&l+d+1>=c))return i()(e)}e.stopPropagation()}(t,e,h.initialClientPos)},h.lockedElements.push(e)})),function(e){if(!n().ios)return;if(e.documentListenerAdded)return;document.addEventListener("touchmove",i(),o({passive:!1})),e.documentListenerAdded=!0}(h)):h.lockedNum<=0&&(h.unLockCallback=f.android?function(e){var t=document.documentElement,n=document.body,o=t.scrollTop||n.scrollTop,i=Object.assign({},t.style),l=Object.assign({},n.style);return t.style.height="100%",t.style.overflow="hidden",n.style.top="-".concat(o,"px"),n.style.width="100%",n.style.height="auto",n.style.position="fixed",n.style.overflow=(null==e?void 0:e.overflowType)||"hidden",function(){t.style.height=i.height||"",t.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach((function(e){n.style[e]=l[e]||""})),"scrollBehavior"in document.documentElement.style?window.scrollTo({top:o,behavior:"instant"}):window.scrollTo(0,o)}}(c):(d=document.documentElement,s=Object.assign({},d.style),u=window.innerWidth-d.clientWidth,a=parseInt(window.getComputedStyle(d).paddingRight,10),d.style.overflow="hidden",d.style.boxSizing="border-box",d.style.paddingRight="".concat(u+a,"px"),function(){["overflow","boxSizing","paddingRight"].forEach((function(e){d.style[e]=s[e]||""}))})),h.lockedNum+=1}},e.unlock=function(e,n){if(!t()){var o=r(n);o.lockedNum-=1,o.lockedNum>0||d(o)||(l(e).forEach((function(e){var t=o.lockedElements.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,o.lockedElements.splice(t,1))})),s(o))}}}));

@@ -14,1 +14,2 @@ import { Nullable } from './types';

export declare function getPreventEventDefault(): (event: TouchEvent) => void;
export declare function toArray<T>(x?: Nullable<T>): T[];
{
"name": "tua-body-scroll-lock",
"version": "1.5.0",
"version": "1.5.1-beta.1",
"packageManager": "pnpm@^7",

@@ -5,0 +5,0 @@ "description": "🔐Body scroll locking that just works with everything",

@@ -15,3 +15,8 @@ import type { BSLOptions, LockState } from './types'

export function getLockState (options?: BSLOptions) {
/**
* get current lockState
* @param options
* @returns lockState
*/
export function getLockState (options?: BSLOptions): LockState {
if (isServer()) return initialLockState

@@ -18,0 +23,0 @@

@@ -1,131 +0,3 @@

import { getLockState } from './getLockState'
import { handleScroll } from './handleScroll'
import { setOverflowHiddenMobile, setOverflowHiddenPc } from './setOverflowHidden'
import type { BSLOptions, Nullable } from './types'
import {
isServer,
detectOS,
getPreventEventDefault,
getEventListenerOptions,
noticeRequiredTargetElement,
} from './utils'
const eventListenerOptions = getEventListenerOptions({ passive: false })
function lock (targetElement?: Nullable<HTMLElement>, options?: BSLOptions) {
if (isServer()) return
noticeRequiredTargetElement(targetElement)
const lockState = getLockState(options)
if (detectOS().ios) {
// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement]
elementArray.forEach((element) => {
if (element && lockState.lockedElements.indexOf(element) === -1) {
element.ontouchstart = (event) => {
const { clientX, clientY } = event.targetTouches[0]
lockState.initialClientPos = { clientX, clientY }
}
element.ontouchmove = (event) => {
if (event.targetTouches.length !== 1) return
handleScroll(event, element, lockState.initialClientPos)
}
lockState.lockedElements.push(element)
}
})
}
if (!lockState.documentListenerAdded) {
document.addEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = true
}
} else if (lockState.lockedNum <= 0) {
lockState.unLockCallback = detectOS().android
? setOverflowHiddenMobile(options)
: setOverflowHiddenPc()
}
lockState.lockedNum += 1
}
function unlock (targetElement?: Nullable<HTMLElement>, options?: BSLOptions) {
if (isServer()) return
noticeRequiredTargetElement(targetElement)
const lockState = getLockState(options)
lockState.lockedNum -= 1
if (lockState.lockedNum > 0) return
if (
!detectOS().ios &&
typeof lockState.unLockCallback === 'function'
) {
lockState.unLockCallback()
return
}
// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement]
elementArray.forEach((element) => {
const index = lockState.lockedElements.indexOf(element)
if (index !== -1) {
element.ontouchmove = null
element.ontouchstart = null
lockState.lockedElements.splice(index, 1)
}
})
}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = false
}
}
function clearBodyLocks (options?: BSLOptions) {
if (isServer()) return
const lockState = getLockState(options)
lockState.lockedNum = 0
if (
!detectOS().ios &&
typeof lockState.unLockCallback === 'function'
) {
lockState.unLockCallback()
return
}
// iOS
if (lockState.lockedElements.length) {
// clear events
let element = lockState.lockedElements.pop()
while (element) {
element.ontouchmove = null
element.ontouchstart = null
element = lockState.lockedElements.pop()
}
}
if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = false
}
}
export * from './types'
export { lock, unlock, clearBodyLocks }
export * from './getLockState'
export { lock, unlock, clearBodyLocks } from './methods'

@@ -53,3 +53,2 @@ import { Nullable } from './types'

if (process.env.NODE_ENV === 'production') return false
/* istanbul ignore if */

@@ -80,1 +79,6 @@ if (process.env.NODE_ENV !== 'test') {

}
export function toArray<T> (x?: Nullable<T>): T[] {
if (!x) return []
return Array.isArray(x) ? x : [x]
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc