Angular directive to observe element visibility within the viewport (IntersectionObserver-based)
npm install angular-view-observer-directivebash
npm install angular-view-observer-directive
`
or with yarn:
`bash
yarn add angular-view-observer-directive
`
Quick Start
$3
The directive is standalone, so you can import it directly in your component:
`typescript
import { Component } from '@angular/core';
import { AngularViewObserverDirective } from 'angular-view-observer-directive';
@Component({
selector: 'app-example',
standalone: true,
imports: [AngularViewObserverDirective],
template:
})
export class ExampleComponent {
onVisibilityChange(isVisible: boolean) {
console.log('Element is visible:', isVisible);
}
}
`
$3
For non-standalone components, import the directive in your module:
`typescript
import { NgModule } from '@angular/core';
import { AngularViewObserverDirective } from 'angular-view-observer-directive';
@NgModule({
imports: [AngularViewObserverDirective],
// ... your other imports
})
export class YourModule { }
`
Usage Examples
$3
`typescript
@Component({
selector: 'app-lazy-load',
standalone: true,
imports: [AngularViewObserverDirective],
template:
})
export class LazyLoadComponent {
imageUrl = '';
onImageVisible(isVisible: boolean) {
if (isVisible) {
this.imageUrl = 'https://example.com/image.jpg';
}
}
}
`
$3
Track visibility with a custom threshold (0 = element must be fully visible, 1 = any part visible):
`typescript
viewObserver
[threshold]="0.5"
(visibleChange)="onVisibilityChange($event)"
>
Content here
$3
Observe element visibility relative to a specific scrollable ancestor:
`typescript
viewObserver
ancestorSelector=".scrollable-container"
(visibleChange)="onVisibilityChange($event)"
>
Element visibility in scrollable container
$3
Execute custom logic with full access to IntersectionObserverEntry:
`typescript
@Component({
selector: 'app-advanced',
standalone: true,
imports: [AngularViewObserverDirective],
template:
})
export class AdvancedComponent {
customCallback = (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => {
entries.forEach(entry => {
console.log('Intersection Ratio:', entry.intersectionRatio);
console.log('Bounding Client Rect:', entry.boundingClientRect);
});
};
onVisibilityChange(isVisible: boolean) {
console.log('Visibility changed:', isVisible);
}
}
`
$3
`typescript
@Component({
selector: 'app-infinite-scroll',
standalone: true,
imports: [CommonModule, AngularViewObserverDirective],
template:
})
export class InfiniteScrollComponent implements OnInit {
items: any[] = [];
constructor(private apiService: ApiService) {}
ngOnInit() {
this.loadItems();
}
onLoadMoreVisible(isVisible: boolean) {
if (isVisible) {
this.loadItems();
}
}
private loadItems() {
this.apiService.getItems().subscribe(newItems => {
this.items = [...this.items, ...newItems];
});
}
}
`
API Reference
$3
#### Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| threshold | number | 0.1 | Visibility threshold (0-1). Determines what percentage of the element must be visible. |
| ancestorSelector | string | undefined | CSS selector for the scrollable ancestor element to use as the observation root. |
| observerCallback | Function | undefined | Custom callback function executed when visibility changes. Receives (entries, observer). |
#### Outputs
| Output | Type | Description |
|--------|------|-------------|
| visibleChange | boolean | Emitted when the element's visibility state changes. Debounced by 11ms. |
Performance Considerations
- Debouncing: The directive debounces visibility events by 11ms to prevent excessive change detection cycles
- Automatic Cleanup: The directive automatically disconnects the IntersectionObserver when the component is destroyed
- No Memory Leaks: Uses Angular's DestroyRef and takeUntilDestroyed for proper cleanup
Browser Support
Works with all modern browsers that support the Intersection Observer API:
- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
For older browsers, consider using a polyfill.
Development
$3
Build the library:
`bash
ng build angular-view-observer-directive
`
The build artifacts will be stored in the dist/angular-view-observer-directive/ directory.
$3
Execute the unit test suite via Karma:
`bash
ng test angular-view-observer-directive
`
$3
Run ng serve for a dev server. Navigate to http://localhost:4200/`. The application will automatically reload if you change any of the source files.