-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
index.ts
81 lines (71 loc) · 1.93 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { computed, ref, watch } from 'vue-demi'
import type { Fn, MaybeComputedRef } from '@vueuse/shared'
import { isIOS, resolveRef, resolveUnref, tryOnScopeDispose } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
function preventDefault(rawEvent: TouchEvent): boolean {
const e = rawEvent || window.event
// Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
if (e.touches.length > 1)
return true
if (e.preventDefault)
e.preventDefault()
return false
}
/**
* Lock scrolling of the element.
*
* @see https://vueuse.org/useScrollLock
* @param element
*/
export function useScrollLock(
element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined>,
initialState = false,
) {
const isLocked = ref(initialState)
let stopTouchMoveListener: Fn | null = null
let initialOverflow: CSSStyleDeclaration['overflow']
watch(resolveRef(element), (el) => {
if (el) {
const ele = el as HTMLElement
initialOverflow = ele.style.overflow
if (isLocked.value)
ele.style.overflow = 'hidden'
}
}, {
immediate: true,
})
const lock = () => {
const ele = (resolveUnref(element) as HTMLElement)
if (!ele || isLocked.value)
return
if (isIOS) {
stopTouchMoveListener = useEventListener(
ele,
'touchmove',
preventDefault,
{ passive: false },
)
}
ele.style.overflow = 'hidden'
isLocked.value = true
}
const unlock = () => {
const ele = (resolveUnref(element) as HTMLElement)
if (!ele || !isLocked.value)
return
isIOS && stopTouchMoveListener?.()
ele.style.overflow = initialOverflow
isLocked.value = false
}
tryOnScopeDispose(unlock)
return computed<boolean>({
get() {
return isLocked.value
},
set(v) {
if (v)
lock()
else unlock()
},
})
}