Skip to content

Commit

Permalink
feat: close #75, export getLockState
Browse files Browse the repository at this point in the history
  • Loading branch information
BuptStEve authored and evinma committed Jul 19, 2024
1 parent 54104f1 commit a8e4909
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 141 deletions.
2 changes: 2 additions & 0 deletions examples/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"preview": "vite preview"
},
"dependencies": {
"@vueuse/core": "^10.11.0",
"radash": "^12.1.0",
"vue": "^3.3.4"
},
"devDependencies": {
Expand Down
18 changes: 15 additions & 3 deletions examples/vue/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@ import ModalTwo from './ModalTwo.vue'
const showModalOne = ref(false)
const showModalTwo = ref(false)
const useGlobalLockState = ref(false)
</script>

<template>
<HeaderPart/>
<GlobalClearBtn/>

<div id="input" @click="useGlobalLockState = !useGlobalLockState">
useGlobalLockState: <input v-model="useGlobalLockState" type="checkbox" />
</div>

<button id="btn" @click="showModalOne = true">
click me to <br />show dialog one
</button>

<ModalOne v-model:visible="showModalOne" @click-btn="showModalTwo = true"/>
<ModalOne v-model:visible="showModalOne" :useGlobalLockState="useGlobalLockState" @click-btn="showModalTwo = true"/>

<ModalTwo v-model:visible="showModalTwo"/>
<ModalTwo v-model:visible="showModalTwo" :useGlobalLockState="useGlobalLockState"/>

<div id="list">
<p v-for="i in 150" :key="i">{{i}} scroll me~</p>
Expand All @@ -30,15 +35,22 @@ const showModalTwo = ref(false)

<style>
#btn {
#input {
position: fixed;
top: 150px;
left: 20px;
}
#btn {
position: fixed;
top: 200px;
left: 20px;
}
#list {
margin: 0 20px;
padding-right: 50px;
text-indent: 100px;
}
button {
Expand Down
16 changes: 13 additions & 3 deletions examples/vue/src/ModalOne.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<script setup lang="ts">
import { useEventListener } from '@vueuse/core'
import { throttle } from 'radash'
import { lock, unlock } from 'tua-body-scroll-lock'
import { ref, watch } from 'vue'
const props = defineProps<{ visible: boolean }>()
import { printLockedNum } from './utils'
const props = defineProps<{
visible: boolean,
useGlobalLockState: boolean,
}>()
const emits = defineEmits<{(e: 'clickBtn'): void, (e: 'update:visible', v: boolean): void}>()
const targetOneRef = ref<HTMLElement>()
Expand All @@ -12,16 +19,19 @@ watch(() => props.visible, () => {
if (props.visible) {
lock(
[targetOneRef.value!, targetTwoRef.value!],
{ overflowType: 'clip', useGlobalLockState: true },
{ overflowType: 'clip', useGlobalLockState: props.useGlobalLockState },
)
} else {
unlock(
[targetOneRef.value!, targetTwoRef.value!],
{ useGlobalLockState: true },
{ useGlobalLockState: props.useGlobalLockState },
)
}
printLockedNum()
})
useEventListener(window, 'scroll', throttle({ interval: 300 }, printLockedNum))
</script>

<template>
Expand Down
12 changes: 9 additions & 3 deletions examples/vue/src/ModalTwo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@
import { lock, unlock } from 'tua-body-scroll-lock'
import { ref, watch } from 'vue'
const props = defineProps<{ visible: boolean }>()
import { printLockedNum } from './utils'
const props = defineProps<{
visible: boolean,
useGlobalLockState: boolean,
}>()
const emits = defineEmits<{(e: 'update:visible', v: boolean): void}>()
const targetThreeRef = ref<HTMLElement>()
watch(() => props.visible, () => {
if (props.visible) {
lock(targetThreeRef.value!, { useGlobalLockState: true })
lock(targetThreeRef.value!, { useGlobalLockState: props.useGlobalLockState })
} else {
unlock(targetThreeRef.value!, { useGlobalLockState: true })
unlock(targetThreeRef.value!, { useGlobalLockState: props.useGlobalLockState })
}
printLockedNum()
})
</script>
Expand Down
5 changes: 5 additions & 0 deletions examples/vue/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { getLockState } from 'tua-body-scroll-lock'

export function printLockedNum () {
console.log('scroll.local:', getLockState({ useGlobalLockState: false }).lockedNum, 'scroll.global:', getLockState({ useGlobalLockState: true }).lockedNum)
}
55 changes: 55 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion src/getLockState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ const initialLockState: LockState = {
},
}

export function getLockState (options?: BSLOptions) {
/**
* get current lockState
* @param options
* @returns lockState
*/
export function getLockState (options?: BSLOptions): LockState {
if (isServer()) return initialLockState

/** use local lockState */
Expand Down
132 changes: 2 additions & 130 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,131 +1,3 @@
import { getLockState } from './getLockState'
import { handleScroll } from './handleScroll'
import { setOverflowHiddenMobile, setOverflowHiddenPc } from './setOverflowHidden'
import type { BSLOptions, Nullable } from './types'
import {
isServer,
detectOS,
getPreventEventDefault,
getEventListenerOptions,
noticeRequiredTargetElement,
} from './utils'

const eventListenerOptions = getEventListenerOptions({ passive: false })

function lock (targetElement?: Nullable<HTMLElement>, options?: BSLOptions) {
if (isServer()) return

noticeRequiredTargetElement(targetElement)

const lockState = getLockState(options)

if (detectOS().ios) {
// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement]

elementArray.forEach((element) => {
if (element && lockState.lockedElements.indexOf(element) === -1) {
element.ontouchstart = (event) => {
const { clientX, clientY } = event.targetTouches[0]
lockState.initialClientPos = { clientX, clientY }
}

element.ontouchmove = (event) => {
if (event.targetTouches.length !== 1) return

handleScroll(event, element, lockState.initialClientPos)
}

lockState.lockedElements.push(element)
}
})
}

if (!lockState.documentListenerAdded) {
document.addEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = true
}
} else if (lockState.lockedNum <= 0) {
lockState.unLockCallback = detectOS().android
? setOverflowHiddenMobile(options)
: setOverflowHiddenPc()
}

lockState.lockedNum += 1
}

function unlock (targetElement?: Nullable<HTMLElement>, options?: BSLOptions) {
if (isServer()) return

noticeRequiredTargetElement(targetElement)

const lockState = getLockState(options)

lockState.lockedNum -= 1
if (lockState.lockedNum > 0) return

if (
!detectOS().ios &&
typeof lockState.unLockCallback === 'function'
) {
lockState.unLockCallback()
return
}

// iOS
if (targetElement) {
const elementArray = Array.isArray(targetElement) ? targetElement : [targetElement]

elementArray.forEach((element) => {
const index = lockState.lockedElements.indexOf(element)

if (index !== -1) {
element.ontouchmove = null
element.ontouchstart = null
lockState.lockedElements.splice(index, 1)
}
})
}

if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = false
}
}

function clearBodyLocks (options?: BSLOptions) {
if (isServer()) return

const lockState = getLockState(options)

lockState.lockedNum = 0

if (
!detectOS().ios &&
typeof lockState.unLockCallback === 'function'
) {
lockState.unLockCallback()
return
}

// iOS
if (lockState.lockedElements.length) {
// clear events
let element = lockState.lockedElements.pop()
while (element) {
element.ontouchmove = null
element.ontouchstart = null

element = lockState.lockedElements.pop()
}
}

if (lockState.documentListenerAdded) {
document.removeEventListener('touchmove', getPreventEventDefault(), eventListenerOptions)
lockState.documentListenerAdded = false
}
}

export * from './types'
export { lock, unlock, clearBodyLocks }
export * from './getLockState'
export { lock, unlock, clearBodyLocks } from './methods'
Loading

0 comments on commit a8e4909

Please sign in to comment.