forked from vitest-dev/vitest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
117 lines (101 loc) · 2.47 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { ref, reactive } from 'vue-demi'
import { useThrottleFn, useDebounceFn, noop, MaybeRef } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
export interface UseScrollOptions {
/**
* Throttle time for scroll event,it’s disabled by default.
*
* @default 0
*/
throttle?: number
/**
* The check time when scrolling ends.
* This configuration will be setting to (throttle + idle) when the `throttle` is configured.
*
* @default 200
*/
idle?: number
/**
* Trigger it when scrolling.
*
*/
onScroll?: () => void
/**
* Trigger it when scrolling ends.
*
*/
onStop?: () => void
/**
* Listener options for scroll event.
*
* @default {capture: false, passive: true}
*/
eventListenerOptions?: boolean | AddEventListenerOptions
}
/**
* Reactive scroll.
*
* @see https://vueuse.org/useScroll
* @param element
* @param options
*/
export function useScroll(
element: MaybeRef<HTMLElement | SVGElement | Window | Document>,
options: UseScrollOptions = {},
) {
const {
throttle = 0,
idle = 200,
onStop = noop,
onScroll = noop,
eventListenerOptions = {
capture: false,
passive: true,
},
}
= options
const x = ref(0)
const y = ref(0)
const isScrolling = ref(false)
const arrivedState = reactive({
left: true,
right: false,
top: true,
bottom: false,
})
if (element) {
const onScrollEnd = useDebounceFn(() => {
isScrolling.value = false
onStop()
}, throttle + idle)
const onScrollHandler = (e: Event) => {
const eventTarget = (e.target === document ? (e.target as Document).documentElement : e.target) as HTMLElement
const scrollLeft = eventTarget.scrollLeft
arrivedState.left = scrollLeft <= 0
arrivedState.right = scrollLeft + eventTarget.clientWidth >= eventTarget.scrollWidth
x.value = scrollLeft
const scrollTop = eventTarget.scrollTop
arrivedState.top = scrollTop <= 0
arrivedState.bottom = scrollTop + eventTarget.clientHeight >= eventTarget.scrollHeight
y.value = scrollTop
isScrolling.value = true
onScrollEnd()
onScroll()
}
useEventListener(
element,
'scroll',
throttle
? useThrottleFn(onScrollHandler, throttle)
: onScrollHandler,
eventListenerOptions,
)
}
return {
x,
y,
isScrolling,
arrivedState,
}
}
export type UseScrollReturn = ReturnType<typeof useScroll>