tua-body-scroll-lock
Version:
🔐Body scroll locking that just works with everything
2 lines (1 loc) • 2.19 kB
JavaScript
const t=()=>"undefined"==typeof window,e=t=>document.querySelector(t),o=t=>{t=t||navigator.userAgent;const e=/(iPad).*OS\s([\d_]+)/.test(t);return{ios:!e&&/(iPhone\sOS)\s([\d_]+)/.test(t)||e,android:/(Android);?[\s\/]+([\d.]+)?/.test(t)}};let n=0,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}),h=t=>{t.cancelable&&t.preventDefault()},a=a=>{t()||(o().ios?(a&&-1===d.indexOf(a)&&(a.ontouchstart=t=>{i=t.targetTouches[0].clientY,s=t.targetTouches[0].clientX},a.ontouchmove=t=>{1===t.targetTouches.length&&((t,e)=>{if(e){const{scrollTop:o,scrollLeft:n,scrollWidth:l,scrollHeight:r,clientWidth:d,clientHeight:c}=e,a=t.targetTouches[0].clientX-s,u=t.targetTouches[0].clientY-i,f=Math.abs(u)>Math.abs(a),g=u>0&&0===o,p=a>0&&0===n,v=a<0&&n+d+1>=l,y=u<0&&o+c+1>=r;if(f&&(g||y)||!f&&(p||v))return h(t)}t.stopPropagation()})(t,a)},d.push(a)),r||(document.addEventListener("touchmove",h,c),r=!0)):n<=0&&(l=o().android?(()=>{const t=e("html"),o=e("body"),n=t.scrollTop||o.scrollTop,i=Object.assign({},t.style),s=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="hidden",()=>{t.style.height=i.height||"",t.style.overflow=i.overflow||"",["top","width","height","overflow","position"].forEach(t=>{o.style[t]=s[t]||""}),window.scrollTo(0,n)}})():(()=>{const t=e("body"),o=Object.assign({},t.style),n=window.innerWidth-document.body.clientWidth;return t.style.overflow="hidden",t.style.boxSizing="border-box",t.style.paddingRight=`${n}px`,()=>{["overflow","boxSizing","paddingRight"].forEach(e=>{t.style[e]=o[e]||""})}})()),n+=1)},u=e=>{if(!(t()||(n-=1)>0))if(o().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",h,c),r=!1)}else l()};export{a as lock,u as unlock};