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 0.2.2 to 0.3.0-0

dist/index.d.ts

170

dist/tua-bsl.esm.browser.js
/**
* tua-body-scroll-lock v0.2.2
* tua-body-scroll-lock v0.3.0-0
* (c) 2019 Evinma, BuptStEve

@@ -7,52 +7,59 @@ * @license MIT

let lockedNum = 0;
let initialClientY = 0;
let unLockCallback = null;
let documentListenerAdded = false;
const isServer = typeof window === 'undefined';
const lockedElements = [];
const $ = !isServer && document.querySelector.bind(document);
let eventListenerOptions;
if (!isServer) {
const testEvent = '__TUA_BSL_TEST_PASSIVE__';
const passiveTestOptions = {
get passive () {
eventListenerOptions = { passive: false };
},
};
window.addEventListener(testEvent, null, passiveTestOptions);
window.removeEventListener(testEvent, null, passiveTestOptions);
}
const detectOS = () => {
const ua = navigator.userAgent;
const isServer = () => typeof window === 'undefined';
const $ = (selector) => document.querySelector(selector);
const detectOS = (ua) => {
ua = ua || navigator.userAgent;
const ipad = /(iPad).*OS\s([\d_]+)/.test(ua);
const iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua);
const android = /(Android);?[\s/]+([\d.]+)?/.test(ua);
const os = android ? 'android' : 'ios';
const ios = iphone || ipad;
return { os, ios, ipad, iphone, android }
return { ios, android };
};
function getEventListenerOptions(options) {
/* istanbul ignore if */
if (isServer())
return false;
if (!options) {
throw new Error('options must be provided');
}
let isSupportOptions = false;
const listenerOptions = {
get passive() {
isSupportOptions = true;
return;
},
};
/* istanbul ignore next */
const noop = () => { };
const testEvent = '__TUA_BSL_TEST_PASSIVE__';
window.addEventListener(testEvent, noop, listenerOptions);
window.removeEventListener(testEvent, noop, listenerOptions);
const { capture } = options;
/* istanbul ignore next */
return isSupportOptions
? options
: typeof capture !== 'undefined'
? capture
: false;
}
let lockedNum = 0;
let initialClientY = 0;
let unLockCallback = null;
let documentListenerAdded = false;
const lockedElements = [];
const eventListenerOptions = getEventListenerOptions({ passive: false });
const setOverflowHiddenPc = () => {
const $body = $('body');
const bodyStyle = { ...$body.style };
const bodyStyle = Object.assign({}, $body.style);
const scrollBarWidth = window.innerWidth - document.body.clientWidth;
$body.style.overflow = 'hidden';
$body.style.boxSizing = 'border-box';
$body.style.paddingRight = `${scrollBarWidth}px`;
return () => {
['overflow', 'boxSizing', 'paddingRight'].forEach((x) => {
['overflow', 'boxSizing', 'paddingRight'].forEach((x) => {
$body.style[x] = bodyStyle[x] || '';
});
}
};
};
const setOverflowHiddenMobile = () => {

@@ -62,8 +69,6 @@ const $html = $('html');

const scrollTop = $html.scrollTop || $body.scrollTop;
const htmlStyle = { ...$html.style };
const bodyStyle = { ...$body.style };
const htmlStyle = Object.assign({}, $html.style);
const bodyStyle = Object.assign({}, $body.style);
$html.style.height = '100%';
$html.style.overflow = 'hidden';
$body.style.top = `-${scrollTop}px`;

@@ -74,24 +79,18 @@ $body.style.width = '100%';

$body.style.overflow = 'hidden';
return () => {
$html.style.height = htmlStyle.height || '';
$html.style.overflow = htmlStyle.overflow || ''
;['top', 'width', 'height', 'overflow', 'position'].forEach((x) => {
$html.style.overflow = htmlStyle.overflow || '';
['top', 'width', 'height', 'overflow', 'position'].forEach((x) => {
$body.style[x] = bodyStyle[x] || '';
});
window.scrollTo(0, scrollTop);
}
};
};
const preventDefault = (event) => {
if (!event.cancelable) return
if (!event.cancelable)
return;
event.preventDefault();
};
const handleScroll = (event, targetElement) => {
const clientY = event.targetTouches[0].clientY - initialClientY;
if (targetElement) {

@@ -101,27 +100,21 @@ const { scrollTop, scrollHeight, clientHeight } = targetElement;

const isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight;
if (isOnTop || isOnBottom) {
return preventDefault(event)
return preventDefault(event);
}
}
event.stopPropagation();
return true
return true;
};
const checkTargetElement = (targetElement) => {
if (targetElement) return
if (targetElement === null) return
console.warn(
`If scrolling is also required in the floating layer, ` +
`the target element must be provided.`
);
if (targetElement)
return;
if (targetElement === null)
return;
console.warn(`If scrolling is also required in the floating layer, ` +
`the target element must be provided.`);
};
const lock = (targetElement) => {
if (isServer) return
if (isServer())
return;
checkTargetElement(targetElement);
if (detectOS().ios) {

@@ -133,12 +126,9 @@ // iOS

};
targetElement.ontouchmove = (event) => {
if (event.targetTouches.length !== 1) return
if (event.targetTouches.length !== 1)
return;
handleScroll(event, targetElement);
};
lockedElements.push(targetElement);
}
if (!documentListenerAdded) {

@@ -148,29 +138,31 @@ document.addEventListener('touchmove', preventDefault, eventListenerOptions);

}
} else if (lockedNum <= 0) {
unLockCallback = detectOS().android ? setOverflowHiddenMobile() : setOverflowHiddenPc();
}
else if (lockedNum <= 0) {
unLockCallback = detectOS().android
? setOverflowHiddenMobile()
: setOverflowHiddenPc();
}
lockedNum += 1;
};
const unlock = (targetElement) => {
if (isServer) return
if (isServer())
return;
checkTargetElement(targetElement);
lockedNum -= 1;
if (lockedNum > 0) return
if (!detectOS().ios) {
lockedNum <= 0 && typeof unLockCallback === 'function' && unLockCallback();
return
if (lockedNum > 0)
return;
if (!detectOS().ios &&
typeof unLockCallback === 'function') {
unLockCallback();
return;
}
// iOS
const index = lockedElements.indexOf(targetElement);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
if (targetElement) {
const index = lockedElements.indexOf(targetElement);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
}
}
if (documentListenerAdded) {

@@ -177,0 +169,0 @@ document.removeEventListener('touchmove', preventDefault, eventListenerOptions);

@@ -1,1 +0,1 @@

let e=0,t=0,o=null,n=!1;const i="undefined"==typeof window,s=[],l=!i&&document.querySelector.bind(document);let r;if(!i){const e="__TUA_BSL_TEST_PASSIVE__",t={get passive(){r={passive:!1}}};window.addEventListener(e,null,t),window.removeEventListener(e,null,t)}const d=()=>{const e=navigator.userAgent,t=/(iPad).*OS\s([\d_]+)/.test(e),o=!t&&/(iPhone\sOS)\s([\d_]+)/.test(e),n=/(Android);?[\s\/]+([\d.]+)?/.test(e);return{os:n?"android":"ios",ios:o||t,ipad:t,iphone:o,android:n}},c=e=>{e.cancelable&&e.preventDefault()},h=h=>{i||(d().ios?(h&&-1===s.indexOf(h)&&(h.ontouchstart=e=>{t=e.targetTouches[0].clientY},h.ontouchmove=e=>{1===e.targetTouches.length&&((e,o)=>{const n=e.targetTouches[0].clientY-t;if(o){const{scrollTop:t,scrollHeight:i,clientHeight:s}=o,l=n<0&&t+s+1>=i;if(n>0&&0===t||l)return c(e)}e.stopPropagation()})(e,h)},s.push(h)),n||(document.addEventListener("touchmove",c,r),n=!0)):e<=0&&(o=d().android?(()=>{const e=l("html"),t=l("body"),o=e.scrollTop||t.scrollTop,n={...e.style},i={...t.style};return e.style.height="100%",e.style.overflow="hidden",t.style.top=`-${o}px`,t.style.width="100%",t.style.height="auto",t.style.position="fixed",t.style.overflow="hidden",()=>{e.style.height=n.height||"",e.style.overflow=n.overflow||"",["top","width","height","overflow","position"].forEach(e=>{t.style[e]=i[e]||""}),window.scrollTo(0,o)}})():(()=>{const e=l("body"),t={...e.style},o=window.innerWidth-document.body.clientWidth;return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight=`${o}px`,()=>{["overflow","boxSizing","paddingRight"].forEach(o=>{e.style[o]=t[o]||""})}})()),e+=1)},u=t=>{if(i)return;if((e-=1)>0)return;if(!d().ios)return void(e<=0&&"function"==typeof o&&o());const l=s.indexOf(t);-1!==l&&(t.ontouchmove=null,t.ontouchstart=null,s.splice(l,1)),n&&(document.removeEventListener("touchmove",c,r),n=!1)};export{h as lock,u as unlock};
const e=()=>"undefined"==typeof window,t=e=>document.querySelector(e),o=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)}};let n=0,i=0,s=null,r=!1;const l=[],d=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=()=>{};window.addEventListener("__TUA_BSL_TEST_PASSIVE__",i,n),window.removeEventListener("__TUA_BSL_TEST_PASSIVE__",i,n);const{capture:s}=t;return o?t:void 0!==s&&s}({passive:!1}),c=e=>{e.cancelable&&e.preventDefault()},h=h=>{e()||(o().ios?(h&&-1===l.indexOf(h)&&(h.ontouchstart=e=>{i=e.targetTouches[0].clientY},h.ontouchmove=e=>{1===e.targetTouches.length&&((e,t)=>{const o=e.targetTouches[0].clientY-i;if(t){const{scrollTop:n,scrollHeight:i,clientHeight:s}=t,r=o<0&&n+s+1>=i;if(o>0&&0===n||r)return c(e)}e.stopPropagation()})(e,h)},l.push(h)),r||(document.addEventListener("touchmove",c,d),r=!0)):n<=0&&(s=o().android?(()=>{const e=t("html"),o=t("body"),n=e.scrollTop||o.scrollTop,i=Object.assign({},e.style),s=Object.assign({},o.style);return e.style.height="100%",e.style.overflow="hidden",o.style.top=`-${n}px`,o.style.width="100%",o.style.height="auto",o.style.position="fixed",o.style.overflow="hidden",()=>{e.style.height=i.height||"",e.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach(e=>{o.style[e]=s[e]||""}),window.scrollTo(0,n)}})():(()=>{const e=t("body"),o=Object.assign({},e.style),n=window.innerWidth-document.body.clientWidth;return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight=`${n}px`,()=>{["overflow","boxSizing","paddingRight"].forEach(t=>{e.style[t]=o[t]||""})}})()),n+=1)},u=t=>{if(!(e()||(n-=1)>0))if(o().ios||"function"!=typeof s){if(t){const e=l.indexOf(t);-1!==e&&(t.ontouchmove=null,t.ontouchstart=null,l.splice(e,1))}r&&(document.removeEventListener("touchmove",c,d),r=!1)}else s()};export{h as lock,u as unlock};
/**
* tua-body-scroll-lock v0.2.2
* tua-body-scroll-lock v0.3.0-0
* (c) 2019 Evinma, BuptStEve

@@ -7,86 +7,64 @@ * @license MIT

function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
const isServer = () => typeof window === 'undefined';
const $ = selector => document.querySelector(selector);
const detectOS = ua => {
ua = ua || navigator.userAgent;
const ipad = /(iPad).*OS\s([\d_]+)/.test(ua);
const iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua);
const android = /(Android);?[\s/]+([\d.]+)?/.test(ua);
const ios = iphone || ipad;
return {
ios,
android
};
};
function getEventListenerOptions(options) {
/* istanbul ignore if */
if (isServer()) return false;
return obj;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function (key) {
_defineProperty(target, key, source[key]);
});
if (!options) {
throw new Error('options must be provided');
}
return target;
}
var lockedNum = 0;
var initialClientY = 0;
var unLockCallback = null;
var documentListenerAdded = false;
var isServer = typeof window === 'undefined';
var lockedElements = [];
var $ = !isServer && document.querySelector.bind(document);
var eventListenerOptions;
if (!isServer) {
var testEvent = '__TUA_BSL_TEST_PASSIVE__';
var passiveTestOptions = {
let isSupportOptions = false;
const listenerOptions = {
get passive() {
eventListenerOptions = {
passive: false
};
isSupportOptions = true;
return;
}
};
window.addEventListener(testEvent, null, passiveTestOptions);
window.removeEventListener(testEvent, null, passiveTestOptions);
}
/* istanbul ignore next */
var detectOS = function detectOS() {
var ua = navigator.userAgent;
var ipad = /(iPad).*OS\s([\d_]+)/.test(ua);
var iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua);
var android = /(Android);?[\s/]+([\d.]+)?/.test(ua);
var os = android ? 'android' : 'ios';
var ios = iphone || ipad;
return {
os: os,
ios: ios,
ipad: ipad,
iphone: iphone,
android: android
};
};
const noop = () => {};
var setOverflowHiddenPc = function setOverflowHiddenPc() {
var $body = $('body');
const testEvent = '__TUA_BSL_TEST_PASSIVE__';
window.addEventListener(testEvent, noop, listenerOptions);
window.removeEventListener(testEvent, noop, listenerOptions);
const {
capture
} = options;
/* istanbul ignore next */
var bodyStyle = _objectSpread({}, $body.style);
return isSupportOptions ? options : typeof capture !== 'undefined' ? capture : false;
}
var scrollBarWidth = window.innerWidth - document.body.clientWidth;
let lockedNum = 0;
let initialClientY = 0;
let unLockCallback = null;
let documentListenerAdded = false;
const lockedElements = [];
const eventListenerOptions = getEventListenerOptions({
passive: false
});
const setOverflowHiddenPc = () => {
const $body = $('body');
const bodyStyle = Object.assign({}, $body.style);
const scrollBarWidth = window.innerWidth - document.body.clientWidth;
$body.style.overflow = 'hidden';
$body.style.boxSizing = 'border-box';
$body.style.paddingRight = "".concat(scrollBarWidth, "px");
return function () {
['overflow', 'boxSizing', 'paddingRight'].forEach(function (x) {
$body.style.paddingRight = `${scrollBarWidth}px`;
return () => {
['overflow', 'boxSizing', 'paddingRight'].forEach(x => {
$body.style[x] = bodyStyle[x] || '';

@@ -97,14 +75,11 @@ });

var setOverflowHiddenMobile = function setOverflowHiddenMobile() {
var $html = $('html');
var $body = $('body');
var scrollTop = $html.scrollTop || $body.scrollTop;
var htmlStyle = _objectSpread({}, $html.style);
var bodyStyle = _objectSpread({}, $body.style);
const setOverflowHiddenMobile = () => {
const $html = $('html');
const $body = $('body');
const scrollTop = $html.scrollTop || $body.scrollTop;
const htmlStyle = Object.assign({}, $html.style);
const bodyStyle = Object.assign({}, $body.style);
$html.style.height = '100%';
$html.style.overflow = 'hidden';
$body.style.top = "-".concat(scrollTop, "px");
$body.style.top = `-${scrollTop}px`;
$body.style.width = '100%';

@@ -114,6 +89,6 @@ $body.style.height = 'auto';

$body.style.overflow = 'hidden';
return function () {
return () => {
$html.style.height = htmlStyle.height || '';
$html.style.overflow = htmlStyle.overflow || '';
['top', 'width', 'height', 'overflow', 'position'].forEach(function (x) {
['top', 'width', 'height', 'overflow', 'position'].forEach(x => {
$body.style[x] = bodyStyle[x] || '';

@@ -125,3 +100,3 @@ });

var preventDefault = function preventDefault(event) {
const preventDefault = event => {
if (!event.cancelable) return;

@@ -131,11 +106,13 @@ event.preventDefault();

var handleScroll = function handleScroll(event, targetElement) {
var clientY = event.targetTouches[0].clientY - initialClientY;
const handleScroll = (event, targetElement) => {
const clientY = event.targetTouches[0].clientY - initialClientY;
if (targetElement) {
var scrollTop = targetElement.scrollTop,
scrollHeight = targetElement.scrollHeight,
clientHeight = targetElement.clientHeight;
var isOnTop = clientY > 0 && scrollTop === 0;
var isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight;
const {
scrollTop,
scrollHeight,
clientHeight
} = targetElement;
const isOnTop = clientY > 0 && scrollTop === 0;
const isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight;

@@ -151,11 +128,11 @@ if (isOnTop || isOnBottom) {

var checkTargetElement = function checkTargetElement(targetElement) {
const checkTargetElement = targetElement => {
if (targetElement) return;
if (targetElement === null) return;
if (process.env.NODE_ENV === 'production') return;
console.warn("If scrolling is also required in the floating layer, " + "the target element must be provided.");
console.warn(`If scrolling is also required in the floating layer, ` + `the target element must be provided.`);
};
var lock = function lock(targetElement) {
if (isServer) return;
const lock = targetElement => {
if (isServer()) return;
checkTargetElement(targetElement);

@@ -166,7 +143,7 @@

if (targetElement && lockedElements.indexOf(targetElement) === -1) {
targetElement.ontouchstart = function (event) {
targetElement.ontouchstart = event => {
initialClientY = event.targetTouches[0].clientY;
};
targetElement.ontouchmove = function (event) {
targetElement.ontouchmove = event => {
if (event.targetTouches.length !== 1) return;

@@ -190,4 +167,4 @@ handleScroll(event, targetElement);

var unlock = function unlock(targetElement) {
if (isServer) return;
const unlock = targetElement => {
if (isServer()) return;
checkTargetElement(targetElement);

@@ -197,4 +174,4 @@ lockedNum -= 1;

if (!detectOS().ios) {
lockedNum <= 0 && typeof unLockCallback === 'function' && unLockCallback();
if (!detectOS().ios && typeof unLockCallback === 'function') {
unLockCallback();
return;

@@ -204,8 +181,10 @@ } // iOS

var index = lockedElements.indexOf(targetElement);
if (targetElement) {
const index = lockedElements.indexOf(targetElement);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
}
}

@@ -212,0 +191,0 @@

/**
* tua-body-scroll-lock v0.2.2
* tua-body-scroll-lock v0.3.0-0
* (c) 2019 Evinma, BuptStEve

@@ -8,213 +8,192 @@ * @license MIT

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.bodyScrollLock = {}));
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.bodyScrollLock = {}));
}(this, function (exports) { 'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
const isServer = () => typeof window === 'undefined';
const $ = selector => document.querySelector(selector);
const detectOS = ua => {
ua = ua || navigator.userAgent;
const ipad = /(iPad).*OS\s([\d_]+)/.test(ua);
const iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua);
const android = /(Android);?[\s/]+([\d.]+)?/.test(ua);
const ios = iphone || ipad;
return {
ios,
android
};
};
function getEventListenerOptions(options) {
/* istanbul ignore if */
if (isServer()) return false;
return obj;
}
if (!options) {
throw new Error('options must be provided');
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
let isSupportOptions = false;
const listenerOptions = {
get passive() {
isSupportOptions = true;
return;
}
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
};
/* istanbul ignore next */
ownKeys.forEach(function (key) {
_defineProperty(target, key, source[key]);
});
}
const noop = () => {};
return target;
}
const testEvent = '__TUA_BSL_TEST_PASSIVE__';
window.addEventListener(testEvent, noop, listenerOptions);
window.removeEventListener(testEvent, noop, listenerOptions);
const {
capture
} = options;
/* istanbul ignore next */
var lockedNum = 0;
var initialClientY = 0;
var unLockCallback = null;
var documentListenerAdded = false;
var isServer = typeof window === 'undefined';
var lockedElements = [];
var $ = !isServer && document.querySelector.bind(document);
var eventListenerOptions;
return isSupportOptions ? options : typeof capture !== 'undefined' ? capture : false;
}
if (!isServer) {
var testEvent = '__TUA_BSL_TEST_PASSIVE__';
var passiveTestOptions = {
get passive() {
eventListenerOptions = {
passive: false
};
}
let lockedNum = 0;
let initialClientY = 0;
let unLockCallback = null;
let documentListenerAdded = false;
const lockedElements = [];
const eventListenerOptions = getEventListenerOptions({
passive: false
});
const setOverflowHiddenPc = () => {
const $body = $('body');
const bodyStyle = Object.assign({}, $body.style);
const scrollBarWidth = window.innerWidth - document.body.clientWidth;
$body.style.overflow = 'hidden';
$body.style.boxSizing = 'border-box';
$body.style.paddingRight = `${scrollBarWidth}px`;
return () => {
['overflow', 'boxSizing', 'paddingRight'].forEach(x => {
$body.style[x] = bodyStyle[x] || '';
});
};
};
window.addEventListener(testEvent, null, passiveTestOptions);
window.removeEventListener(testEvent, null, passiveTestOptions);
}
var detectOS = function detectOS() {
var ua = navigator.userAgent;
var ipad = /(iPad).*OS\s([\d_]+)/.test(ua);
var iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua);
var android = /(Android);?[\s/]+([\d.]+)?/.test(ua);
var os = android ? 'android' : 'ios';
var ios = iphone || ipad;
return {
os: os,
ios: ios,
ipad: ipad,
iphone: iphone,
android: android
const setOverflowHiddenMobile = () => {
const $html = $('html');
const $body = $('body');
const scrollTop = $html.scrollTop || $body.scrollTop;
const htmlStyle = Object.assign({}, $html.style);
const bodyStyle = Object.assign({}, $body.style);
$html.style.height = '100%';
$html.style.overflow = 'hidden';
$body.style.top = `-${scrollTop}px`;
$body.style.width = '100%';
$body.style.height = 'auto';
$body.style.position = 'fixed';
$body.style.overflow = 'hidden';
return () => {
$html.style.height = htmlStyle.height || '';
$html.style.overflow = htmlStyle.overflow || '';
['top', 'width', 'height', 'overflow', 'position'].forEach(x => {
$body.style[x] = bodyStyle[x] || '';
});
window.scrollTo(0, scrollTop);
};
};
};
var setOverflowHiddenPc = function setOverflowHiddenPc() {
var $body = $('body');
var bodyStyle = _objectSpread({}, $body.style);
var scrollBarWidth = window.innerWidth - document.body.clientWidth;
$body.style.overflow = 'hidden';
$body.style.boxSizing = 'border-box';
$body.style.paddingRight = "".concat(scrollBarWidth, "px");
return function () {
['overflow', 'boxSizing', 'paddingRight'].forEach(function (x) {
$body.style[x] = bodyStyle[x] || '';
});
const preventDefault = event => {
if (!event.cancelable) return;
event.preventDefault();
};
};
var setOverflowHiddenMobile = function setOverflowHiddenMobile() {
var $html = $('html');
var $body = $('body');
var scrollTop = $html.scrollTop || $body.scrollTop;
const handleScroll = (event, targetElement) => {
const clientY = event.targetTouches[0].clientY - initialClientY;
var htmlStyle = _objectSpread({}, $html.style);
if (targetElement) {
const {
scrollTop,
scrollHeight,
clientHeight
} = targetElement;
const isOnTop = clientY > 0 && scrollTop === 0;
const isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight;
var bodyStyle = _objectSpread({}, $body.style);
if (isOnTop || isOnBottom) {
return preventDefault(event);
}
}
$html.style.height = '100%';
$html.style.overflow = 'hidden';
$body.style.top = "-".concat(scrollTop, "px");
$body.style.width = '100%';
$body.style.height = 'auto';
$body.style.position = 'fixed';
$body.style.overflow = 'hidden';
return function () {
$html.style.height = htmlStyle.height || '';
$html.style.overflow = htmlStyle.overflow || '';
['top', 'width', 'height', 'overflow', 'position'].forEach(function (x) {
$body.style[x] = bodyStyle[x] || '';
});
window.scrollTo(0, scrollTop);
event.stopPropagation();
return true;
};
};
var preventDefault = function preventDefault(event) {
if (!event.cancelable) return;
event.preventDefault();
};
const checkTargetElement = targetElement => {
if (targetElement) return;
if (targetElement === null) return;
console.warn(`If scrolling is also required in the floating layer, ` + `the target element must be provided.`);
};
var handleScroll = function handleScroll(event, targetElement) {
var clientY = event.targetTouches[0].clientY - initialClientY;
const lock = targetElement => {
if (isServer()) return;
checkTargetElement(targetElement);
if (targetElement) {
var scrollTop = targetElement.scrollTop,
scrollHeight = targetElement.scrollHeight,
clientHeight = targetElement.clientHeight;
var isOnTop = clientY > 0 && scrollTop === 0;
var isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight;
if (detectOS().ios) {
// iOS
if (targetElement && lockedElements.indexOf(targetElement) === -1) {
targetElement.ontouchstart = event => {
initialClientY = event.targetTouches[0].clientY;
};
if (isOnTop || isOnBottom) {
return preventDefault(event);
targetElement.ontouchmove = event => {
if (event.targetTouches.length !== 1) return;
handleScroll(event, targetElement);
};
lockedElements.push(targetElement);
}
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, eventListenerOptions);
documentListenerAdded = true;
}
} else if (lockedNum <= 0) {
unLockCallback = detectOS().android ? setOverflowHiddenMobile() : setOverflowHiddenPc();
}
}
event.stopPropagation();
return true;
};
lockedNum += 1;
};
var checkTargetElement = function checkTargetElement(targetElement) {
if (targetElement) return;
if (targetElement === null) return;
console.warn("If scrolling is also required in the floating layer, " + "the target element must be provided.");
};
const unlock = targetElement => {
if (isServer()) return;
checkTargetElement(targetElement);
lockedNum -= 1;
if (lockedNum > 0) return;
var lock = function lock(targetElement) {
if (isServer) return;
checkTargetElement(targetElement);
if (!detectOS().ios && typeof unLockCallback === 'function') {
unLockCallback();
return;
} // iOS
if (detectOS().ios) {
// iOS
if (targetElement && lockedElements.indexOf(targetElement) === -1) {
targetElement.ontouchstart = function (event) {
initialClientY = event.targetTouches[0].clientY;
};
targetElement.ontouchmove = function (event) {
if (event.targetTouches.length !== 1) return;
handleScroll(event, targetElement);
};
if (targetElement) {
const index = lockedElements.indexOf(targetElement);
lockedElements.push(targetElement);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
}
}
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, eventListenerOptions);
documentListenerAdded = true;
if (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, eventListenerOptions);
documentListenerAdded = false;
}
} else if (lockedNum <= 0) {
unLockCallback = detectOS().android ? setOverflowHiddenMobile() : setOverflowHiddenPc();
}
};
lockedNum += 1;
};
exports.lock = lock;
exports.unlock = unlock;
var unlock = function unlock(targetElement) {
if (isServer) return;
checkTargetElement(targetElement);
lockedNum -= 1;
if (lockedNum > 0) return;
Object.defineProperty(exports, '__esModule', { value: true });
if (!detectOS().ios) {
lockedNum <= 0 && typeof unLockCallback === 'function' && unLockCallback();
return;
} // iOS
var index = lockedElements.indexOf(targetElement);
if (index !== -1) {
targetElement.ontouchmove = null;
targetElement.ontouchstart = null;
lockedElements.splice(index, 1);
}
if (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, eventListenerOptions);
documentListenerAdded = false;
}
};
exports.lock = lock;
exports.unlock = unlock;
Object.defineProperty(exports, '__esModule', { value: true });
}));

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).bodyScrollLock={})}(this,function(e){"use strict";function t(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function o(e){for(var o=1;o<arguments.length;o++){var n=null!=arguments[o]?arguments[o]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(o){t(e,o,n[o])})}return e}var n,i=0,r=0,l=null,c=!1,s="undefined"==typeof window,u=[],d=!s&&document.querySelector.bind(document);if(!s){var f={get passive(){n={passive:!1}}};window.addEventListener("__TUA_BSL_TEST_PASSIVE__",null,f),window.removeEventListener("__TUA_BSL_TEST_PASSIVE__",null,f)}var a=function(){var e=navigator.userAgent,t=/(iPad).*OS\s([\d_]+)/.test(e),o=!t&&/(iPhone\sOS)\s([\d_]+)/.test(e),n=/(Android);?[\s\/]+([\d.]+)?/.test(e);return{os:n?"android":"ios",ios:o||t,ipad:t,iphone:o,android:n}},h=function(e){e.cancelable&&e.preventDefault()};e.lock=function(e){var t,f,y,p,v;s||(a().ios?(e&&-1===u.indexOf(e)&&(e.ontouchstart=function(e){r=e.targetTouches[0].clientY},e.ontouchmove=function(t){1===t.targetTouches.length&&function(e,t){var o=e.targetTouches[0].clientY-r;if(t){var n=t.scrollTop,i=t.scrollHeight,l=t.clientHeight;if(o>0&&0===n||o<0&&n+l+1>=i)return h(e)}e.stopPropagation()}(t,e)},u.push(e)),c||(document.addEventListener("touchmove",h,n),c=!0)):i<=0&&(l=a().android?(t=d("html"),f=d("body"),y=t.scrollTop||f.scrollTop,p=o({},t.style),v=o({},f.style),t.style.height="100%",t.style.overflow="hidden",f.style.top="-".concat(y,"px"),f.style.width="100%",f.style.height="auto",f.style.position="fixed",f.style.overflow="hidden",function(){t.style.height=p.height||"",t.style.overflow=p.overflow||"",["top","width","height","overflow","position"].forEach(function(e){f.style[e]=v[e]||""}),window.scrollTo(0,y)}):function(){var e=d("body"),t=o({},e.style),n=window.innerWidth-document.body.clientWidth;return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight="".concat(n,"px"),function(){["overflow","boxSizing","paddingRight"].forEach(function(o){e.style[o]=t[o]||""})}}()),i+=1)},e.unlock=function(e){if(!(s||(i-=1)>0))if(a().ios){var t=u.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,u.splice(t,1)),c&&(document.removeEventListener("touchmove",h,n),c=!1)}else i<=0&&"function"==typeof l&&l()},Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).bodyScrollLock={})}(this,function(e){"use strict";const t=()=>"undefined"==typeof window,o=e=>document.querySelector(e),n=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)}};let i=0,s=0,l=null,r=!1;const d=[],c=function(e){if(t())return!1;if(!e)throw new Error("options must be provided");let o=!1;const n={get passive(){o=!0}},i=()=>{};window.addEventListener("__TUA_BSL_TEST_PASSIVE__",i,n),window.removeEventListener("__TUA_BSL_TEST_PASSIVE__",i,n);const{capture:s}=e;return o?e:void 0!==s&&s}({passive:!1}),u=e=>{e.cancelable&&e.preventDefault()};e.lock=e=>{t()||(n().ios?(e&&-1===d.indexOf(e)&&(e.ontouchstart=e=>{s=e.targetTouches[0].clientY},e.ontouchmove=t=>{1===t.targetTouches.length&&((e,t)=>{const o=e.targetTouches[0].clientY-s;if(t){const{scrollTop:n,scrollHeight:i,clientHeight:s}=t,l=o<0&&n+s+1>=i;if(o>0&&0===n||l)return u(e)}e.stopPropagation()})(t,e)},d.push(e)),r||(document.addEventListener("touchmove",u,c),r=!0)):i<=0&&(l=n().android?(()=>{const e=o("html"),t=o("body"),n=e.scrollTop||t.scrollTop,i=Object.assign({},e.style),s=Object.assign({},t.style);return e.style.height="100%",e.style.overflow="hidden",t.style.top=`-${n}px`,t.style.width="100%",t.style.height="auto",t.style.position="fixed",t.style.overflow="hidden",()=>{e.style.height=i.height||"",e.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach(e=>{t.style[e]=s[e]||""}),window.scrollTo(0,n)}})():(()=>{const e=o("body"),t=Object.assign({},e.style),n=window.innerWidth-document.body.clientWidth;return e.style.overflow="hidden",e.style.boxSizing="border-box",e.style.paddingRight=`${n}px`,()=>{["overflow","boxSizing","paddingRight"].forEach(o=>{e.style[o]=t[o]||""})}})()),i+=1)},e.unlock=e=>{if(!(t()||(i-=1)>0))if(n().ios||"function"!=typeof l){if(e){const t=d.indexOf(e);-1!==t&&(e.ontouchmove=null,e.ontouchstart=null,d.splice(t,1))}r&&(document.removeEventListener("touchmove",u,c),r=!1)}else l()},Object.defineProperty(e,"__esModule",{value:!0})});
{
"name": "tua-body-scroll-lock",
"version": "0.2.2",
"version": "0.3.0-0",
"description": "🔐Body scroll locking that just works with everything",

@@ -9,6 +9,11 @@ "main": "dist/tua-bsl.umd.js",

"jsdelivr": "dist/tua-bsl.umd.js",
"typings": "src/index.d.ts",
"typings": "dist/index.d.ts",
"scripts": {
"cov": "open coverage/lcov-report/index.html",
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
"lint": "eslint --fix ./",
"start": "rollup -c -w",
"test": "npm run type-check && cross-env NODE_ENV=test jest",
"test:tdd": "cross-env NODE_ENV=test jest --watch",
"build": "npm run lint && rollup -c && cp index.html dist/index.html",

@@ -44,6 +49,12 @@ "next": "npm --no-git-tag-version version prerelease",

"@babel/preset-env": "^7.3.1",
"@babel/preset-typescript": "^7.3.3",
"@commitlint/cli": "^7.5.2",
"@commitlint/config-conventional": "^7.5.0",
"@types/jest": "^24.0.17",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"all-contributors-cli": "^6.3.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.8.0",
"cross-env": "^5.2.0",
"eslint-config-standard": "^12.0.0",

@@ -56,2 +67,4 @@ "eslint-plugin-import": "^2.16.0",

"husky": "^1.3.1",
"jest": "^24.8.0",
"jest-environment-jsdom-thirteen": "^1.0.1",
"lint-staged": "^8.1.4",

@@ -63,3 +76,5 @@ "rollup": "^1.2.2",

"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-terser": "^5.0.0"
"rollup-plugin-terser": "^5.0.0",
"rollup-plugin-typescript2": "^0.22.1",
"typescript": "^3.5.3"
},

@@ -66,0 +81,0 @@ "repository": {

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