tua-body-scroll-lock
Advanced tools
Comparing version 0.2.2 to 0.3.0-0
/** | ||
* 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": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
42655
13
683
30
1