Skip to content

Commit 07d3985

Browse files
ziolko-appfireMateusz Zielińskiantfu
authoredDec 4, 2023
fix(useElementVisibility): use last intersection entry (#3365)
Co-authored-by: Mateusz Zieliński <mateusz.zielinski@spartez-software.com> Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 9c72d5c commit 07d3985

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed
 

‎packages/core/useElementVisibility/index.test.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('useElementVisibility', () => {
4141
it('passes a callback to useIntersectionObserver that sets visibility to false only when isIntersecting is false', () => {
4242
const isVisible = useElementVisibility(el)
4343
const callback = vi.mocked(useIntersectionObserver).mock.lastCall?.[1]
44-
const callMockCallbackWithIsIntersectingValue = (isIntersecting: boolean) => callback?.([{ isIntersecting } as IntersectionObserverEntry], {} as IntersectionObserver)
44+
const callMockCallbackWithIsIntersectingValue = (isIntersecting: boolean) => callback?.([{ isIntersecting, time: 1 } as IntersectionObserverEntry], {} as IntersectionObserver)
4545

4646
// It should be false initially
4747
expect(isVisible.value).toBe(false)
@@ -59,6 +59,34 @@ describe('useElementVisibility', () => {
5959
expect(isVisible.value).toBe(false)
6060
})
6161

62+
it('uses the latest version of isIntersecting when multiple intersection entries are given', () => {
63+
const isVisible = useElementVisibility(el)
64+
const callback = vi.mocked(useIntersectionObserver).mock.lastCall?.[1]
65+
const callMockCallbackWithIsIntersectingValues = (...entries: { isIntersecting: boolean; time: number }[]) => {
66+
callback?.(entries as IntersectionObserverEntry[], {} as IntersectionObserver)
67+
}
68+
69+
// It should be false initially
70+
expect(isVisible.value).toBe(false)
71+
72+
// It should take the latest value of isIntersecting
73+
callMockCallbackWithIsIntersectingValues(
74+
{ isIntersecting: false, time: 1 },
75+
{ isIntersecting: false, time: 2 },
76+
{ isIntersecting: true, time: 3 },
77+
)
78+
expect(isVisible.value).toBe(true)
79+
80+
// It should take the latest even when entries are out of order
81+
callMockCallbackWithIsIntersectingValues(
82+
{ isIntersecting: true, time: 1 },
83+
{ isIntersecting: false, time: 3 },
84+
{ isIntersecting: true, time: 2 },
85+
)
86+
87+
expect(isVisible.value).toBe(false)
88+
})
89+
6290
it('passes the given window to useIntersectionObserver', () => {
6391
const mockWindow = {} as Window
6492

‎packages/core/useElementVisibility/index.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@ export function useElementVisibility(
2323

2424
useIntersectionObserver(
2525
element,
26-
([{ isIntersecting }]) => {
26+
(intersectionObserverEntries) => {
27+
let isIntersecting = elementIsVisible.value
28+
29+
// Get the latest value of isIntersecting based on the entry time
30+
let latestTime = 0
31+
for (const entry of intersectionObserverEntries) {
32+
if (entry.time >= latestTime) {
33+
latestTime = entry.time
34+
isIntersecting = entry.isIntersecting
35+
}
36+
}
2737
elementIsVisible.value = isIntersecting
2838
},
2939
{

0 commit comments

Comments
 (0)
Please sign in to comment.