New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.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.1.0 to 0.2.0-0

.all-contributorsrc

29

package.json
{
"name": "tua-body-scroll-lock",
"version": "0.1.0",
"description": "Body scroll locking that just works with everything",
"main": "lib/tua-bsl.umd.js",
"module": "lib/tua-bsl.esm.js",
"unpkg": "lib/tua-bsl.umd.js",
"jsdelivr": "lib/tua-bsl.umd.js",
"version": "0.2.0-0",
"description": "🔐Body scroll locking that just works with everything",
"main": "dist/tua-bsl.umd.js",
"module": "dist/tua-bsl.esm.js",
"unpkg": "dist/tua-bsl.umd.js",
"jsdelivr": "dist/tua-bsl.umd.js",
"typings": "src/index.d.ts",
"scripts": {
"lint": "eslint --fix ./",
"start": "rollup -c -w",
"build": "npm run lint && rollup -c && cp index.html lib/index.html",
"lint": "eslint --fix ./",
"deploy": "npm run build && gh-pages -d lib"
"build": "npm run lint && rollup -c && cp index.html dist/index.html",
"next": "npm --no-git-tag-version version prerelease",
"next:m": "npm --no-git-tag-version version preminor",
"pub": "npm run build && npm publish",
"pub:n": "npm run build && npm publish --tag next",
"deploy": "npm run build && gh-pages -d dist"
},
"eslintIgnore": [
"lib/"
"dist/"
],

@@ -38,2 +42,3 @@ "husky": {

"@commitlint/config-conventional": "^7.5.0",
"all-contributors-cli": "^6.3.0",
"babel-eslint": "^10.0.1",

@@ -50,6 +55,4 @@ "eslint-config-standard": "^12.0.0",

"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-eslint": "^5.0.0",
"rollup-plugin-json": "^3.1.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-replace": "^2.1.0",

@@ -85,4 +88,4 @@ "rollup-plugin-uglify": "^6.0.2"

],
"author": "evinma",
"author": "Evinma, BuptStEve",
"license": "MIT"
}

@@ -5,7 +5,26 @@ # tua-body-scroll-lock

## 介绍
顾名思义 `tua-body-scroll-lock` 是用来锁住 `body` 滚动的包。并且针对`PC端`和移动端 `ios` 和 `android` 做了不同的处理,保证在各个端都可以完美使用。
<img src="https://img.shields.io/badge/dependencies-none-green.svg" alt="dependencies">
<a href="https://www.npmjs.com/package/tua-body-scroll-lock" target="_blank">
<img src="https://badgen.net/npm/dm/tua-body-scroll-lock" alt="Downloads per month">
<img src="https://img.shields.io/npm/v/tua-body-scroll-lock.svg" alt="Version">
<img src="https://img.shields.io/npm/v/tua-body-scroll-lock/next.svg" alt="Next Version">
<img src="https://img.shields.io/npm/l/tua-body-scroll-lock.svg" alt="License">
</a>
## 安装
English | [简体中文](./README-zh_CN.md)
## Introduction
`tua-body-scroll-lock` enables body scroll locking for everything.
### Why not [body-scroll-lock](https://github.com/willmcpo/body-scroll-lock)?
* Doesn't work on Android webview
* Doesn't work on PC with mouse wheel
* Doesn't work on iOS, if you touch somewhere instead of targetElement
* Must pass targetElement, even if it's not necessary
[Try This](https://codepen.io/buptsteve/pen/EJoKQK)
## Install
### Node Package Manager(recommended)
```bash

@@ -17,18 +36,29 @@ $ npm i -S tua-body-scroll-lock

## 使用
### CDN
* UMD(`tua-bsl.umd.js`)
* [unpkg](https://unpkg.com/tua-body-scroll-lock)
* [jsdelivr](https://cdn.jsdelivr.net/npm/tua-body-scroll-lock)
### 移动端
```html
<!-- unpkg -->
<script src="https://unpkg.com/tua-body-scroll-lock"></script>
```js
import { lock, unlock } from 'tua-body-scroll-lock'
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/tua-body-scroll-lock"></script>
```
// 禁止滑动后还需要内部可以滚动的元素(针对移动端ios处理)
const targetElement = document.querySelector("#someElementId");
* Minified UMD(`tua-bsl.umd.min.js`)
* [unpkg](https://unpkg.com/tua-body-scroll-lock/dist/tua-bsl.umd.min.js)
* [jsdelivr](https://cdn.jsdelivr.net/npm/tua-body-scroll-lock/dist/tua-bsl.umd.min.js)
lock(targetElement)
unlock(targetElement)
```html
<!-- unpkg -->
<script src="https://unpkg.com/tua-body-scroll-lock/dist/tua-bsl.umd.min.js"></script>
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/tua-body-scroll-lock/dist/tua-bsl.umd.min.js"></script>
```
### PC端
> tips: PC端不需要targetElement; 不传targetElement也不想要控制台提示可以传`null`
## Usage
### Normal

@@ -42,5 +72,31 @@ ```js

## 测试
[测试链接](https://tuateam.github.io/tua-body-scroll-lock)
### TargetElement needs scrolling(iOS only)
In some scenarios, when scrolling is prohibited, some elements still need to scroll, at this point, pass the targetElement.
```js
import { lock, unlock } from 'tua-body-scroll-lock'
const targetElement = document.querySelector('#someElementId')
lock(targetElement)
unlock(targetElement)
```
> The `targetElement` is not required on the PC and Android.
## Test
[testLink](https://tuateam.github.io/tua-body-scroll-lock)
![bodyScrollLock](./tua-bsl.png)
## Contributors
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table><tr><td align="center"><a href="https://github.com/evinma"><img src="https://avatars2.githubusercontent.com/u/16096567?v=4" width="100px;" alt="evinma"/><br /><sub><b>evinma</b></sub></a><br /><a href="https://github.com/tuateam/tua-body-scroll-lock/commits?author=evinma" title="Code">💻</a> <a href="https://github.com/tuateam/tua-body-scroll-lock/commits?author=evinma" title="Documentation">📖</a></td><td align="center"><a href="https://buptsteve.github.io"><img src="https://avatars2.githubusercontent.com/u/11501493?v=4" width="100px;" alt="StEve Young"/><br /><sub><b>StEve Young</b></sub></a><br /><a href="https://github.com/tuateam/tua-body-scroll-lock/commits?author=BuptStEve" title="Documentation">📖</a> <a href="#infra-BuptStEve" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td><td align="center"><a href="https://github.com/li2go"><img src="https://avatars2.githubusercontent.com/u/11485337?v=4" width="100px;" alt="li2go"/><br /><sub><b>li2go</b></sub></a><br /><a href="https://github.com/tuateam/tua-body-scroll-lock/issues?q=author%3Ali2go" title="Bug reports">🐛</a></td><td align="center"><a href="https://github.com/feitiange"><img src="https://avatars3.githubusercontent.com/u/7125157?v=4" width="100px;" alt="songyan,Wang"/><br /><sub><b>songyan,Wang</b></sub></a><br /><a href="https://github.com/tuateam/tua-body-scroll-lock/issues?q=author%3Afeitiange" title="Bug reports">🐛</a></td></tr></table>
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

@@ -1,64 +0,63 @@

// import json from 'rollup-plugin-json'
import babel from 'rollup-plugin-babel'
import replace from 'rollup-plugin-replace'
import { eslint } from 'rollup-plugin-eslint'
import commonjs from 'rollup-plugin-commonjs'
import { uglify } from 'rollup-plugin-uglify'
import nodeResolve from 'rollup-plugin-node-resolve'
const pkg = require('./package.json')
const plugins = [
// json(),
eslint(),
babel(),
commonjs(),
nodeResolve({ jsnext: true, main: true, browser: true }),
]
const banner =
`/**
* ${pkg.name} v${pkg.version}
* (c) ${new Date().getFullYear()} ${pkg.author}
* @license ${pkg.license}
*/
`
const plugins = [ eslint(), babel() ]
export default [
{
input: 'src/index.js',
output: [
{
file: pkg.module,
// exports: 'named',
format: 'es',
},
],
plugins,
const configMap = {
esm: {
file: pkg.module,
format: 'esm',
},
{
input: 'src/index.js',
output: [
{
file: pkg.main,
format: 'umd',
exports: 'named',
name: 'bodyScrollLock',
},
],
plugins: [
...plugins,
replace({
'process.env.NODE_ENV': true,
}),
],
umdDev: {
file: pkg.main,
format: 'umd',
env: 'development',
},
{
umdProd: {
file: `dist/tua-bsl.umd.min.js`,
format: 'umd',
env: 'production',
},
}
const genConfig = (opts) => {
const isProd = /min\.js$/.test(opts.file)
const config = {
input: 'src/index.js',
plugins: plugins.slice(),
output: {
file: `lib/tua-bsl.umd.min.js`,
format: 'umd',
exports: 'named',
file: opts.file,
format: opts.format,
banner,
name: 'bodyScrollLock',
},
plugins: [
...plugins,
replace({
'process.env.NODE_ENV': false,
}),
uglify(),
],
},
]
}
if (opts.env) {
config.plugins.push(replace({
'process.env.NODE_ENV': JSON.stringify(opts.env),
}))
}
if (isProd) {
config.plugins.push(uglify())
}
return config
}
export default Object.keys(configMap)
.map(key => configMap[key])
.map(genConfig)

@@ -1,17 +0,21 @@

let locksElement = []
let lockedNum = 0
let initialClientY
let unLockCallback
let documentListenerAdded
let initialClientY = 0
let unLockCallback = null
let documentListenerAdded = false
let hasPassiveEvents = false
if (typeof window !== 'undefined') {
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 () {
hasPassiveEvents = true
return undefined
eventListenerOptions = { passive: false }
},
}
window.addEventListener('testPassive', null, passiveTestOptions)
window.removeEventListener('testPassive', null, passiveTestOptions)
window.addEventListener(testEvent, null, passiveTestOptions)
window.removeEventListener(testEvent, null, passiveTestOptions)
}

@@ -21,29 +25,25 @@

const ua = navigator.userAgent
const android = /(Android);?[\s/]+([\d.]+)?/.test(ua)
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: android ? 'android' : 'ios',
ios,
ipad,
iphone,
android,
}
return { os, ios, ipad, iphone, android }
}
const setOverflowHiddenPc = () => {
const $ = document::document.querySelector
const $body = $('body')
const bodyStyle = { ...$body.style }
const scrollBarWidth = window.innerWidth - document.body.clientWidth
$body.style.overflow = 'hidden'
$body.style.paddingRight = scrollBarWidth + 'px'
$body.style.boxSizing = 'border-box'
$body.style.paddingRight = `${scrollBarWidth}px`
return () => {
$body.style.overflow = bodyStyle.overflow || ''
$body.style.paddingRight = bodyStyle.paddingRight || ''
$body.style.boxSizing = bodyStyle.boxSizing || ''
;['overflow', 'boxSizing', 'paddingRight'].forEach((x) => {
$body.style[x] = bodyStyle[x] || ''
})
}

@@ -53,28 +53,24 @@ }

const setOverflowHiddenMobile = () => {
const $ = document::document.querySelector
const $html = $('html')
const $body = $('body')
const scrollTop = $html.scrollTop || $body.scrollTop
const htmlStyle = { ...$html.style }
const bodyStyle = { ...$body.style }
const scrollTop = $html.scrollTop || $body.scrollTop
$html.style.height = '100%'
$html.style.overflow = 'hidden'
$html.style.height = '100%'
$body.style.overflow = 'hidden'
$body.style.top = `-${scrollTop}px`
$body.style.width = '100%'
$body.style.position = 'fixed'
$body.style.overflow = 'hidden'
return () => {
$html.style.height = htmlStyle.height || ''
$html.style.overflow = htmlStyle.overflow || ''
$html.style.height = htmlStyle.height || ''
$body.style.overflow = bodyStyle.overflow || ''
$body.style.height = bodyStyle.height || ''
$body.style.width = bodyStyle.width || ''
$body.style.position = ''
$body.style.top = ''
;['top', 'width', 'height', 'overflow', 'position'].forEach((x) => {
$body.style[x] = bodyStyle[x] || ''
})
window.scrollTo(0, scrollTop)

@@ -84,6 +80,6 @@ }

const preventDefault = event => {
if (event.cancelable) {
event.preventDefault()
}
const preventDefault = (event) => {
if (!event.cancelable) return
event.preventDefault()
}

@@ -94,8 +90,10 @@

if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
return preventDefault(event)
}
if (targetElement) {
const { scrollTop, scrollHeight, clientHeight } = targetElement
const isOnTop = clientY > 0 && scrollTop === 0
const isOnBottom = clientY < 0 && scrollTop + clientHeight + 1 >= scrollHeight
if (targetElement && (targetElement.scrollHeight - 1 - targetElement.scrollTop <= targetElement.clientHeight) && clientY < 0) {
return preventDefault(event)
if (isOnTop || isOnBottom) {
return preventDefault(event)
}
}

@@ -108,52 +106,70 @@

const checkTargetElement = (targetElement) => {
if (!targetElement && targetElement !== null && process.env.NODE_ENV !== 'production') {
console.warn('If scrolling is also required in the floating layer, the target element must be provided')
}
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.`
)
}
export const lock = (targetElement) => {
const lock = (targetElement) => {
if (isServer) return
checkTargetElement(targetElement)
if (detectOS().ios) {
if (targetElement && locksElement.indexOf(targetElement) < 0) {
targetElement.ontouchstart = event => {
// iOS
if (targetElement && lockedElements.indexOf(targetElement) === -1) {
targetElement.ontouchstart = (event) => {
initialClientY = event.targetTouches[0].clientY
}
targetElement.ontouchmove = event => {
if (event.targetTouches.length === 1) {
handleScroll(event, targetElement)
}
targetElement.ontouchmove = (event) => {
if (event.targetTouches.length !== 1) return
handleScroll(event, targetElement)
}
locksElement.push(targetElement)
lockedElements.push(targetElement)
}
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined)
document.addEventListener('touchmove', preventDefault, eventListenerOptions)
documentListenerAdded = true
}
} else {
} else if (lockedNum <= 0) {
unLockCallback = detectOS().android ? setOverflowHiddenMobile() : setOverflowHiddenPc()
}
lockedNum += 1
}
export const unlock = (targetElement) => {
const unlock = (targetElement) => {
if (isServer) return
checkTargetElement(targetElement)
lockedNum -= 1
if (lockedNum > 0 && !targetElement) return
if (detectOS().ios) {
const targetElementIndex = locksElement.indexOf(targetElement)
if (targetElementIndex > -1) {
targetElement.ontouchstart = null
targetElement.ontouchmove = null
locksElement.splice(targetElementIndex, 1)
}
if (documentListenerAdded && lockedNum <= 0) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined)
documentListenerAdded = false
}
} else {
lockedNum <= 0 && unLockCallback()
if (lockedNum > 0) return
if (!detectOS().ios) {
lockedNum <= 0 && 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 (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, eventListenerOptions)
documentListenerAdded = false
}
}
export { lock, unlock }
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true,
"baseUrl": ".",
"experimentalDecorators": true,
"paths":{

@@ -7,0 +7,0 @@ "@/*": ["src/*"],

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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