tua-body-scroll-lock
Advanced tools
Comparing version 1.5.0 to 1.5.1-beta.1
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 { |
@@ -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 @@ |
132
src/index.ts
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
69385
27
1285
2