The answer given by Martin Cremer is perfect.
Unless you want this to work on a angular app using ssr
Angular Universal
I have modified the existing accepted answer to work in ssr below
Create an injectable service to be able to use window object in backend
import { Injectable } from '@angular/core';
export interface ICustomWindow extends Window {
__custom_global_stuff: string;
}
function getWindow (): any {
return window;
}
@Injectable({
providedIn: 'root',
})
export class WindowService {
get nativeWindow (): ICustomWindow {
return getWindow();
}
}
Now, create a directive to notify when the element is in viewable area
import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
import { WindowService } from './window.service';
@Directive({
selector: '[appear]'
})
export class AppearDirective {
windowHeight: number = 0;
elementHeight: number = 0;
elementPos: number = 0;
@Output()
appear: EventEmitter<boolean>;
constructor(
private element: ElementRef,
private window: WindowService
) {
this.appear = new EventEmitter<boolean>();
}
checkVisible() {
if (this.elementPos < this.window.nativeWindow.scrollY + this.windowHeight) {
this.appear.emit(true);
this.appear.complete();
}
}
@HostListener('window:scroll', [])
onScroll() {
this.checkVisible();
}
@HostListener('window:load', [])
onLoad() {
this.windowHeight = (this.window.nativeWindow.innerHeight);
this.elementHeight = (this.element.nativeElement as HTMLElement).offsetHeight;
this.elementPos = (this.element.nativeElement as HTMLElement).offsetTop;
this.checkVisible();
}
@HostListener('window:resize', [])
onResize() {
this.windowHeight = (this.window.nativeWindow.innerHeight);
this.elementHeight = (this.element.nativeElement as HTMLElement).offsetHeight;
this.elementPos = (this.element.nativeElement as HTMLElement).offsetTop;
this.checkVisible();
}
}
Create a new function in the component
onAppear() {
// TODO: do something
}
Add the directive to your element
<!-- ... -->
<h2 (appear)="onAppear()">Visible</h2>
<!-- ... -->