Skip to content

Commit 4b336c4

Browse files
Mini-ghostantfu
andauthored
feat(useIntersectionObserver): support for Pausable interface (#2883)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 5c82cf3 commit 4b336c4

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

packages/core/useIntersectionObserver/demo.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const root = ref(null)
66
const target = ref(null)
77
const isVisible = ref(false)
88
9-
useIntersectionObserver(
9+
const { isActive, pause, resume } = useIntersectionObserver(
1010
target,
1111
([{ isIntersecting }]) => {
1212
isVisible.value = isIntersecting
@@ -16,6 +16,15 @@ useIntersectionObserver(
1616
</script>
1717

1818
<template>
19+
<div class="text-center">
20+
<label class="checkbox">
21+
<input
22+
:checked="isActive" type="checkbox" name="enabled"
23+
@input="($event.target as HTMLInputElement)!.checked ? resume() : pause() "
24+
>
25+
<span>Enable</span>
26+
</label>
27+
</div>
1928
<div ref="root" class="root">
2029
<p class="notice">
2130
Scroll me down!
@@ -40,7 +49,7 @@ useIntersectionObserver(
4049
.root {
4150
border: 2px dashed #ccc;
4251
height: 200px;
43-
margin: 0 2rem 1rem;
52+
margin: 2rem 1rem;
4453
overflow-y: scroll;
4554
}
4655
.notice {

packages/core/useIntersectionObserver/index.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
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'
24
import { noop, tryOnScopeDispose } from '@vueuse/shared'
35
import type { ConfigurableWindow } from '../_configurable'
46
import { defaultWindow } from '../_configurable'
@@ -7,6 +9,13 @@ import { unrefElement } from '../unrefElement'
79
import { useSupported } from '../useSupported'
810

911
export interface UseIntersectionObserverOptions extends ConfigurableWindow {
12+
/**
13+
* Start the IntersectionObserver immediately on creation
14+
*
15+
* @default true
16+
*/
17+
immediate?: boolean
18+
1019
/**
1120
* The Element or Document whose bounds are used as the bounding box when testing for intersection.
1221
*/
@@ -23,6 +32,11 @@ export interface UseIntersectionObserverOptions extends ConfigurableWindow {
2332
threshold?: number | number[]
2433
}
2534

35+
export interface UseIntersectionObserverReturn extends Pausable {
36+
isSupported: Ref<boolean>
37+
stop: () => void
38+
}
39+
2640
/**
2741
* Detects that a target element's visibility.
2842
*
@@ -35,34 +49,36 @@ export function useIntersectionObserver(
3549
target: MaybeComputedElementRef,
3650
callback: IntersectionObserverCallback,
3751
options: UseIntersectionObserverOptions = {},
38-
) {
52+
): UseIntersectionObserverReturn {
3953
const {
4054
root,
4155
rootMargin = '0px',
4256
threshold = 0.1,
4357
window = defaultWindow,
58+
immediate = true,
4459
} = options
4560

4661
const isSupported = useSupported(() => window && 'IntersectionObserver' in window)
4762

4863
let cleanup = noop
64+
const isActive = ref(immediate)
4965

5066
const stopWatch = isSupported.value
5167
? 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]) => {
5770
cleanup()
5871

72+
if (!isActive.value)
73+
return
74+
5975
if (!el)
6076
return
6177

6278
const observer = new IntersectionObserver(
6379
callback,
6480
{
65-
root,
81+
root: unrefElement(root),
6682
rootMargin,
6783
threshold,
6884
},
@@ -74,21 +90,28 @@ export function useIntersectionObserver(
7490
cleanup = noop
7591
}
7692
},
77-
{ immediate: true, flush: 'post' },
93+
{ immediate, flush: 'post' },
7894
)
7995
: noop
8096

8197
const stop = () => {
8298
cleanup()
8399
stopWatch()
100+
isActive.value = false
84101
}
85102

86103
tryOnScopeDispose(stop)
87104

88105
return {
89106
isSupported,
107+
isActive,
108+
pause() {
109+
cleanup()
110+
isActive.value = false
111+
},
112+
resume() {
113+
isActive.value = true
114+
},
90115
stop,
91116
}
92117
}
93-
94-
export type UseIntersectionObserverReturn = ReturnType<typeof useIntersectionObserver>

0 commit comments

Comments
 (0)