1
- import { watch } from 'vue-demi'
1
+ import type { Ref } from 'vue-demi'
2
+ import { ref , watch } from 'vue-demi'
3
+ import type { Pausable } from '@vueuse/shared'
2
4
import { noop , tryOnScopeDispose } from '@vueuse/shared'
3
5
import type { ConfigurableWindow } from '../_configurable'
4
6
import { defaultWindow } from '../_configurable'
@@ -7,6 +9,13 @@ import { unrefElement } from '../unrefElement'
7
9
import { useSupported } from '../useSupported'
8
10
9
11
export interface UseIntersectionObserverOptions extends ConfigurableWindow {
12
+ /**
13
+ * Start the IntersectionObserver immediately on creation
14
+ *
15
+ * @default true
16
+ */
17
+ immediate ?: boolean
18
+
10
19
/**
11
20
* The Element or Document whose bounds are used as the bounding box when testing for intersection.
12
21
*/
@@ -23,6 +32,11 @@ export interface UseIntersectionObserverOptions extends ConfigurableWindow {
23
32
threshold ?: number | number [ ]
24
33
}
25
34
35
+ export interface UseIntersectionObserverReturn extends Pausable {
36
+ isSupported : Ref < boolean >
37
+ stop : ( ) => void
38
+ }
39
+
26
40
/**
27
41
* Detects that a target element's visibility.
28
42
*
@@ -35,34 +49,36 @@ export function useIntersectionObserver(
35
49
target : MaybeComputedElementRef ,
36
50
callback : IntersectionObserverCallback ,
37
51
options : UseIntersectionObserverOptions = { } ,
38
- ) {
52
+ ) : UseIntersectionObserverReturn {
39
53
const {
40
54
root,
41
55
rootMargin = '0px' ,
42
56
threshold = 0.1 ,
43
57
window = defaultWindow ,
58
+ immediate = true ,
44
59
} = options
45
60
46
61
const isSupported = useSupported ( ( ) => window && 'IntersectionObserver' in window )
47
62
48
63
let cleanup = noop
64
+ const isActive = ref ( immediate )
49
65
50
66
const stopWatch = isSupported . value
51
67
? watch (
52
- ( ) => ( {
53
- el : unrefElement ( target ) ,
54
- root : unrefElement ( root ) ,
55
- } ) ,
56
- ( { el, root } ) => {
68
+ ( ) => [ unrefElement ( target ) , unrefElement ( root ) , isActive . value ] as const ,
69
+ ( [ el , root ] ) => {
57
70
cleanup ( )
58
71
72
+ if ( ! isActive . value )
73
+ return
74
+
59
75
if ( ! el )
60
76
return
61
77
62
78
const observer = new IntersectionObserver (
63
79
callback ,
64
80
{
65
- root,
81
+ root : unrefElement ( root ) ,
66
82
rootMargin,
67
83
threshold,
68
84
} ,
@@ -74,21 +90,28 @@ export function useIntersectionObserver(
74
90
cleanup = noop
75
91
}
76
92
} ,
77
- { immediate : true , flush : 'post' } ,
93
+ { immediate, flush : 'post' } ,
78
94
)
79
95
: noop
80
96
81
97
const stop = ( ) => {
82
98
cleanup ( )
83
99
stopWatch ( )
100
+ isActive . value = false
84
101
}
85
102
86
103
tryOnScopeDispose ( stop )
87
104
88
105
return {
89
106
isSupported,
107
+ isActive,
108
+ pause ( ) {
109
+ cleanup ( )
110
+ isActive . value = false
111
+ } ,
112
+ resume ( ) {
113
+ isActive . value = true
114
+ } ,
90
115
stop,
91
116
}
92
117
}
93
-
94
- export type UseIntersectionObserverReturn = ReturnType < typeof useIntersectionObserver >
0 commit comments