Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: Understand if DOM element is within viewport

Basically I would like to flag a dom element with an @input value, i.e. 'aos'

<div aos>my</div>

And then for example do a console log whenever such div is within my viewport.

How can this be achieved? I assume using Angular's Scrolling Dispatcher, but how can I understand that such div is in the viewport?

like image 284
Teabag2000 Avatar asked Sep 30 '20 01:09

Teabag2000


1 Answers

LIVE DEMO

You can use an IntersectionObserver for doing that. It's a native browser API, not an Angular one. One approach is to build a directive that, when applied to any element will tell you that element is visible/hidden. You can check its API here.

Basically what you have to do in this directive is:

  1. Inject the parent of the directive (ElemenRef)
  2. Observe the parent using an IntersectionObserver
@Directive({selector: "[enterTheViewportNotifier]"})
export class EnterTheViewportNotifierDirective implements AfterViewInit, OnDestroy {
  @Output() visibilityChange = new EventEmitter<'VISIBLE' | 'HIDDEN'>();
  private _observer: IntersectionObserver;

  constructor(@Host() private _elementRef: ElementRef) {}

  ngAfterViewInit(): void {
    const options = {root: null,rootMargin: "0px",threshold: 0.0};
    this._observer = new IntersectionObserver(this._callback, options);
    this._observer.observe(this._elementRef.nativeElement);
  }

  ngOnDestroy() {this._observer.disconnect();}

  private _callback = (entries, observer) => {
    entries.forEach(entry => 
        this.visibilityChange.emit(entry.isIntersecting ? 'VISIBLE' : 'HIDDEN'));
  };
}

And you can use it like this (_visibilityChangeHandler will be called with a message everytime the below div enters/leaves the viewport):

<div (visibilityChange)="_visibilityChangeHandler($event)"
     enterTheViewportNotifier>
</div>
like image 188
julianobrasil Avatar answered Nov 03 '22 23:11

julianobrasil