@@ -38,6 +38,7 @@ export function observe(
3838 visible : false ,
3939 options,
4040 observerId,
41+ observer : ! observerId ? observerInstance : undefined ,
4142 } )
4243
4344 observerInstance . observe ( element )
@@ -52,20 +53,24 @@ export function unobserve(element) {
5253 if ( ! element ) return
5354
5455 if ( INSTANCE_MAP . has ( element ) ) {
55- const { observerId } = INSTANCE_MAP . get ( element )
56- const observerInstance = OBSERVER_MAP . get ( observerId )
56+ const { observerId, observer } = INSTANCE_MAP . get ( element )
57+ const observerInstance = observerId
58+ ? OBSERVER_MAP . get ( observerId )
59+ : observer
5760
5861 if ( observerInstance ) {
5962 observerInstance . unobserve ( element )
6063 }
6164
6265 // Check if we are stilling observing any elements with the same threshold.
6366 let itemsLeft = false
64- INSTANCE_MAP . forEach ( ( item , key ) => {
65- if ( item . observerId === observerId && key !== element ) {
66- itemsLeft = true
67- }
68- } )
67+ if ( observerId ) {
68+ INSTANCE_MAP . forEach ( ( item , key ) => {
69+ if ( item . observerId === observerId && key !== element ) {
70+ itemsLeft = true
71+ }
72+ } )
73+ }
6974
7075 if ( observerInstance && ! itemsLeft ) {
7176 // No more elements to observe for threshold, disconnect observer
@@ -94,20 +99,21 @@ function onChange(changes) {
9499 changes . forEach ( intersection => {
95100 if ( INSTANCE_MAP . has ( intersection . target ) ) {
96101 const { isIntersecting, intersectionRatio, target } = intersection
97- const { callback , visible , options , observerId } = INSTANCE_MAP . get (
98- target ,
99- )
102+ const instance = INSTANCE_MAP . get ( target )
103+ const options = instance . options
104+
100105 let inView
101106
102107 if ( Array . isArray ( options . threshold ) ) {
108+ // If threshold is an array, check if any of them intersects. This just triggers the onChange event multiple times.
103109 inView = options . threshold . some ( threshold => {
104- return visible
110+ return instance . visible
105111 ? intersectionRatio > threshold
106112 : intersectionRatio >= threshold
107113 } )
108114 } else {
109115 // Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
110- inView = visible
116+ inView = instance . visible
111117 ? intersectionRatio > options . threshold
112118 : intersectionRatio >= options . threshold
113119 }
@@ -118,15 +124,11 @@ function onChange(changes) {
118124 inView = inView && isIntersecting
119125 }
120126
121- INSTANCE_MAP . set ( target , {
122- callback,
123- visible : inView ,
124- options,
125- observerId,
126- } )
127+ // Update the visible value on the instance
128+ instance . visible = inView
127129
128- if ( callback ) {
129- callback ( inView )
130+ if ( instance . callback ) {
131+ instance . callback ( inView )
130132 }
131133 }
132134 } )
0 commit comments