{"bugs":{"url":"https://github.com/willmcpo/body-scroll-lock/issues"},"dist":{"shasum":"f956f634ffa72aa1994a9dd9d3d3eb5bcc8c7708","tarball":"https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-2.6.0-beta.1.tgz","fileCount":2063,"integrity":"sha512-RF2/inTeXSudevMfxCz7JH7SyP/HMRXTP+Ayzh103ZQK2iO6v2kR7b3ppf+Hy/xqQJfom6LI5+bkhQK+SjTKVA==","signatures":[{"sig":"MEUCIQD3Mg79BAiMTdPGjdVWR56hqepgKh8vTHyuBIvYRWC6pgIgZtCW6Pv6TG0qwFdYCfX1FZPhQeTdWKRn2dYfve9K2nU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":6784656,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb9/IWCRA9TVsSAnZWagAAkMcP/RetGQDS8ers6v94zfSN\nNmsmqIErtsduraARVjO5k2GlbLYebtCY905ycLbvz+wQ/03rADPcjQ+4Wstt\nZumT1KUkvgIgQUZCfEECEwo2/8aSBxs8K9coVkgGpQ7y4cXrOJ+BeuJRYHEg\nMFk9tc+6HYFW3mvZfToIhCifytRosh8ePf8nCqWXn7IbR9/SG6BgA5UZw2fY\nyNYGMLUctM1kkYELknhCY9TO7azcO6QLp/UDjTUELvHF4IUgV8jk64mmxySV\ndR5D8pT9Sra6VM/G0lPjFMFRTZGBmHMKduuX+okpe889Km5Y0a4kCtKxD843\nV+QQnhsViifKLNKGLi1dB3D507yVld/QRwwkOd2ZBNO5s6Y1+ldPBU5+cc5V\n66EFaVh7HCZIIAVt0Vo+HZAJcBO7n30/WeuYMFK5s80MvRGxl+d98k3ZKB0M\nChxryi8hKaDw301GV06Zg0anHW7AF7zrvNESBgDkEu6+/+IG3jp66+5wZhMG\nUN398G04TFP3X6ObNEy8v4mCSGE2gY3vHC22WVpIgz7rcizFWCJnR+oVRbrZ\nvlDCrU01NTD8hjzYNv2rCPvXMk7DOLi4khqOxRjHCARaQ6XW7BANAHt5GFdG\nlM4Za5yNc8XYZS3vE5P8CDDTMp33y7EggYqXC4LBo2XotTcLG7NEoFYbtKtK\nuouL\r\n=cEh0\r\n-----END PGP SIGNATURE-----\r\n"},"main":"lib/bodyScrollLock.min.js","name":"body-scroll-lock","author":{"name":"Will Po"},"readme":"<p align=\"left\"> <img width=\"675\" src=\"https://raw.githubusercontent.com/willmcpo/body-scroll-lock/master/images/logo.png\" alt=\"Body scroll lock...just works with everything ;-)\" /> </p>\n\n## Why BSL?\nEnables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus).\n\n*Features:*\n\n- disables body scroll WITHOUT disabling scroll of a target element\n- works on iOS mobile/tablet (!!)\n- works on Android\n- works on Safari desktop\n- works on Chrome/Firefox \n- works with vanilla JS and frameworks such as React / Angular / VueJS\n- supports nested target elements (eg. a modal that appears on top of a flyout)\n- can reserve scrollbar width\n- `-webkit-overflow-scrolling: touch` still works\n\n*Aren't the alternative approaches sufficient?*\n\n- the approach `document.body.ontouchmove = (e) => { e.preventDefault; return false; };` locks the\nbody scroll, but ALSO locks the scroll of a target element (eg. modal).\n- the approach `overflow: hidden` on the body or html elements doesn't work for all browsers\n- the `position: fixed` approach causes the body scroll to reset\n- some approaches break inertia/momentum/rubber-band scrolling on iOS\n\n*Package Size:*\n\n- LIGHT - package is only 2.8KB and 1.1KB when gzipped (see [here](https://bundlephobia.com/result?p=body-scroll-lock))!\n\n## Install\n\n    $ yarn add body-scroll-lock\n    \n    or\n    \n    $ npm install body-scroll-lock\n    \n    \n    \nYou can also load via a `<script src='lib/bodyScrollLock.js></script>` tag (refer to the lib folder).\n\n\n## Usage examples\n\n##### Common JS\n```javascript\n// 1. Import the functions\nconst bodyScrollLock = require('body-scroll-lock');\nconst disableBodyScroll = bodyScrollLock.disableBodyScroll;\nconst enableBodyScroll = bodyScrollLock.enableBodyScroll;\n  \n// 2. Get an optional target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). \nconst targetElement = document.querySelector(\"#someElementId\");\n  \n  \n// 3. ...in some event handler after showing the target element...disable body scroll\ndisableBodyScroll(targetElement);\n \n \n// 4. ...in some event handler after hiding the target element...\nenableBodyScroll(targetElement);\n```\n  \n  \n##### React/ES6\n```javascript\n// 1. Import the functions\nimport { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';\n  \nclass SomeComponent extends React.Component {\n  targetElement = null;\n  \n  componentDidMount() {\n    // 2. Get an optional target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). \n    this.targetElement = document.querySelector('#targetElementId');\n  }\n  \n  showTargetElement = () => {\n    // ... some logic to show target element\n    \n    // 3. Disable body scroll\n    disableBodyScroll(this.targetElement);\n  };\n  \n  hideTargetElement = () => {\n    // ... some logic to hide target element\n    \n    // 4. Re-enable body scroll\n    enableBodyScroll(this.targetElement);\n  }\n  \n  componentWillUnmount() {\n    // 5. Useful if we have called disableBodyScroll for multiple target elements,\n    // and we just want a kill-switch to undo all that.\n    // OR useful for if the `hideTargetElement()` function got circumvented eg. visitor \n    // clicks a link which takes him/her to a different page within the app.\n    clearAllBodyScrollLocks();\n  }\n\n  render() {   \n    return (\n      <div>\n        some JSX to go here\n      </div> \n    );\n  }\n}\n```\n\n##### React/ES6 with Refs\n```javascript\n// 1. Import the functions\nimport { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';\n  \nclass SomeComponent extends React.Component {\n  // 2. Initialise your ref and targetElement here\n  targetRef = React.createRef();\n  targetElement = null;\n\n  componentDidMount() {\n    // 3. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). \n    this.targetElement = this.targetRef.current; \n  }\n  \n  showTargetElement = () => {\n    // ... some logic to show target element\n    \n    // 4. Disable body scroll\n    disableBodyScroll(this.targetElement);\n  };\n  \n  hideTargetElement = () => {\n    // ... some logic to hide target element\n    \n    // 5. Re-enable body scroll\n    enableBodyScroll(this.targetElement);\n  }\n  \n  componentWillUnmount() {\n    // 5. Useful if we have called disableBodyScroll for multiple target elements,\n    // and we just want a kill-switch to undo all that.\n    // OR useful for if the `hideTargetElement()` function got circumvented eg. visitor \n    // clicks a link which takes him/her to a different page within the app.\n    clearAllBodyScrollLocks();\n  }\n\n  render() {   \n    return (\n      // 6. Pass your ref with the reference to the targetElement to SomeOtherComponent\n      <SomeOtherComponent ref={this.targetElement}>\n        some JSX to go here\n      </SomeOtherComponent> \n    );\n  }\n}\n\n// 7. SomeOtherComponent needs to be a Class component to receive the ref (unless Hooks - https://reactjs.org/docs/hooks-faq.html#can-i-make-a-ref-to-a-function-component - are used).\nclass SomeOtherComponent extends React.Component {\n\n  componentDidMount() {\n    // Your logic on mount goes here\n  }\n\n  // 8. BSL will be applied to div below in SomeOtherComponent and persist scrolling for the container\n  render() {   \n    return (\n      <div>\n        some JSX to go here\n      </div> \n    );\n  }\n}\n```\n\n##### Vanilla JS\nIn the html:\n```html\n<head>\n  <script src=\"some-path-where-you-dump-the-javascript-libraries/lib/bodyScrollLock.js\"></script>\n</head>\n```\n\nThen in the javascript:\n\n```javascript\n// 1. Get an optional target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). \nconst targetElement = document.querySelector(\"#someElementId\");\n\n// 2. ...in some event handler after showing the target element...disable body scroll\nbodyScrollLock.disableBodyScroll(targetElement);\n\n// 3. ...in some event handler after hiding the target element...\nbodyScrollLock.enableBodyScroll(targetElement);\n\n// 4. Useful if we have called disableBodyScroll for multiple target elements,\n// and we just want a kill-switch to undo all that.\nbodyScrollLock.clearAllBodyScrollLocks();\n```\n\n## Demo\nCheck out the demo, powered by Now, @ https://bodyscrolllock.now.sh\n\n## Caveat\n~~On iOS mobile (as is visible in the above demo), if you scroll the body directly even when the scrolling is \nlocked (on iOS), the body scrolls - this is not what this package solves. It solves the typical case where a modal \noverlays the screen, and scrolling within the modal never causes the body to scroll too (when the top or bottom \nwithin the modal has been reached).~~\n\nSince the update from @Neddz, this caveat is no longer valid. iOS mobile behaviour should be the same as \nother devices (eg. Android Chrome). \n\n## Functions\n\n| Function | Arguments | Return | Description |\n| :--- | :--- | :---: | :--- |\n| `disableBodyScroll` | `targetElement?: HTMLElement` | `void` | Disables body scroll while enabling scroll on target element |\n| `enableBodyScroll` | `targetElement?: HTMLElement`<br/>`options: BodyScrollOptions` | `void` | Enables body scroll and removing listeners on target element |\n| `clearAllBodyScrollLocks` | `null` | `void` | Clears all scroll locks |\n\n## Options\n### reserveScrollBarGap\n**optional, default:** false\n\nIf the overflow property of the body is set to hidden, the body widens by the width of the scrollbar. This produces an\nunpleasant flickering effect, especially on websites with centered content. If the `reserveScrollBarGap` option is set,\nthis gap is filled by a `padding-right` on the body element. If `disableBodyScroll` is called for the last target element,\nor `clearAllBodyScrollLocks` is called, the `padding-right` is automatically reset to the previous value.\n``` js\nimport { enableBodyScroll } from 'body-scroll-lock';\nimport type { BodyScrollOptions } from 'body-scroll-lock';\n\nconst options: BodyScrollOptions = {\n    reserveScrollBarGap: true\n}\n\nenableBodyScroll(targetElement, options);\n```\n\n### allowTouchMove\n**optional, default:** undefined\n\nThere are cases where you have called `disableBodyScroll` on an element, but you still want some or all\nchildren of it to receive touch moves still; or in other words, you want child elements to\nignore the fact that a parent element has the body scroll lock set (and hence, not be affected at all by this setting).\nSee below for 2 use cases:\n\n##### Simple \n```javascript\n  disableBodyScroll(container, {\n    allowTouchMove: el => (el.tagName === 'TEXTAREA')\n  });\n```\n\n##### More Complex\nJavascript:\n```javascript\n  disableBodyScroll(container, {\n    allowTouchMove: el => {\n      while (el && el !== document.body) {\n        if (el.getAttribute('body-scroll-lock-ignore') !== null) {\n          return true\n        }\n  \n        el = el.parentNode\n      }\n    },\n  });\n```\nHtml:\n```html\n  <div id=\"container\">\n    <div id=\"scrolling-map\" body-scroll-lock-ignore>\n      ...\n    </div>\n  </div>\n```\n\n## References\nhttps://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177\n\nhttps://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi\n","gitHead":"3b0312131e2a68bb4a9ae54e9ee3f67fe3948b1d","license":"MIT","scripts":{"flow":"flow","lint":"eslint ./src","build":"yarn buildEs6 && yarn buildEs5","clean":"rimraf lib/ && mkdir -p ./lib","release":"npm version","buildEs5":"babel src/bodyScrollLock.js > lib/bodyScrollLock.js && uglifyjs --compress unused,dead_code --mangle reserved=['require','exports'] lib/bodyScrollLock.js > lib/bodyScrollLock.min.js","buildEs6":"babel --plugins transform-flow-strip-types --no-babelrc src/bodyScrollLock.js > lib/bodyScrollLock.es6.js","precommit":"lint-staged","prerelease":"yarn flow && yarn lint && yarn run clean && yarn build","postrelease":"yarn publish && git push --follow-tags","prettierAll":"prettier --write --single-quote --trailing-comma es5 --print-width 120 'src/**/*.js'"},"_npmUser":{"name":"willmcpo","email":"wilson.po@gmail.com"},"homepage":"https://github.com/willmcpo/body-scroll-lock#readme","keywords":["body scroll","body scroll lock","react scroll lock","react scroll","scroll","lock","freeze","toggle","disable","overflow","modal","lightbox","react","vanilla-js","angular","vue","ios","mobile","desktop","tablet","bsl"],"repository":{"url":"git+https://github.com/willmcpo/body-scroll-lock.git","type":"git"},"_npmVersion":"5.6.0","description":"Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus)","directories":{},"lint-staged":{"*.js":["prettier --write --single-quote --trailing-comma es5 --print-width 120","git add"]},"maintainers":[{"name":"willmcpo","email":"wilson.po@gmail.com"}],"_nodeVersion":"9.11.2","dependencies":{},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^22.1.2","husky":"^0.14.3","eslint":"^4.15.0","rimraf":"^2.6.2","flow-bin":"^0.86.0","prettier":"^1.10.2","babel-cli":"^6.26.0","uglify-js":"^3.4.7","lint-staged":"^6.0.1","babel-eslint":"^8.2.1","babel-preset-env":"^1.6.1","babel-preset-flow":"^6.23.0","eslint-config-babel":"^7.0.2","babel-preset-stage-0":"^6.24.1","eslint-plugin-import":"^2.8.0","eslint-plugin-flowtype":"^2.41.0","eslint-config-airbnb-base":"^12.1.0","babel-plugin-transform-flow-strip-types":"^6.22.0"},"_npmOperationalInternal":{"tmp":"tmp/body-scroll-lock_2.6.0-beta.1_1542976021845_0.8612525015476848","host":"s3://npm-registry-packages"},"_id":"body-scroll-lock@2.6.0-beta.1","version":"2.6.0-beta.1"}