1- import { Injectable , OnDestroy } from '@angular/core' ;
1+ import { isPlatformServer } from '@angular/common' ;
2+ import { ElementRef , inject , Injectable , OnDestroy , PLATFORM_ID } from '@angular/core' ;
23import { BehaviorSubject } from 'rxjs' ;
34
45export interface IIntersectionObserverInit {
@@ -7,40 +8,58 @@ export interface IIntersectionObserverInit {
78 threshold ?: number | number [ ] ;
89}
910
10- @Injectable ( )
11+ @Injectable (
12+ { providedIn : 'root' }
13+ )
1114export class IntersectionService implements OnDestroy {
1215
13- constructor ( ) { }
16+ platformId = inject ( PLATFORM_ID ) ;
1417
15- private intersecting = new BehaviorSubject < boolean > ( false ) ;
16- intersecting$ = this . intersecting . asObservable ( ) ;
18+ readonly # intersecting = new BehaviorSubject < boolean > ( false ) ;
19+ readonly intersecting$ = this . # intersecting. asObservable ( ) ;
1720
1821 private intersectionObserver ! : IntersectionObserver ;
19- private hostElement ! : { nativeElement : Element ; } ;
22+ private hostElement ! : ElementRef ;
2023
2124 private defaultObserverOptions : IIntersectionObserverInit = {
2225 root : null ,
2326 rootMargin : '0px' ,
2427 threshold : 0.2
2528 } ;
2629
27- createIntersectionObserver ( hostElement : { nativeElement : Element ; } , observerOptions = this . defaultObserverOptions ) {
30+ hostElementRefs : Map < ElementRef , IntersectionObserver | null > = new Map ( ) ;
2831
29- const options = { ...this . defaultObserverOptions , ...observerOptions } ;
32+ createIntersectionObserver ( hostElement : ElementRef , observerOptions = this . defaultObserverOptions ) {
33+
34+ if ( isPlatformServer ( this . platformId ) ) {
35+ this . #intersecting. next ( true ) ;
36+ return ;
37+ }
3038
31- this . hostElement = hostElement ;
39+ // this.hostElement = hostElement;
40+ const options = { ...this . defaultObserverOptions , ...observerOptions } ;
3241
33- const handleIntersect = ( entries : any [ ] , observer : any ) => {
42+ const handleIntersect = ( entries : IntersectionObserverEntry [ ] , observer : IntersectionObserver ) => {
3443 entries . forEach ( ( entry : any ) => {
35- this . intersecting . next ( entry . isIntersecting ) ;
44+ this . # intersecting. next ( entry . isIntersecting ) ;
3645 } ) ;
3746 } ;
3847
39- this . intersectionObserver = new IntersectionObserver ( handleIntersect , options ) ;
40- this . intersectionObserver . observe ( hostElement . nativeElement ) ;
48+ const intersectionObserver : IntersectionObserver = new IntersectionObserver ( handleIntersect , options ) ;
49+ intersectionObserver . observe ( hostElement . nativeElement ) ;
50+ this . hostElementRefs . set ( hostElement , intersectionObserver ) ;
51+
52+ }
53+
54+ unobserve ( elementRef : ElementRef ) {
55+ this . hostElementRefs . get ( elementRef ) ?. unobserve ( elementRef . nativeElement ) ;
56+ this . hostElementRefs . set ( elementRef , null ) ;
57+ this . hostElementRefs . delete ( elementRef ) ;
4158 }
4259
4360 ngOnDestroy ( ) : void {
44- this . intersectionObserver ?. unobserve ( this . hostElement ?. nativeElement ) ;
61+ this . hostElementRefs . forEach ( ( observer , elementRef ) => {
62+ observer ?. unobserve ( elementRef . nativeElement ) ;
63+ } ) ;
4564 }
4665}
0 commit comments