UNPKG

@trendster-io/ng-lazy-image

Version:

An Angular directive to efficiently lazy load images using the IntersectionObserver API.

150 lines (146 loc) 3.76 kB
import { EventEmitter, Directive, ElementRef, Input, Output, HostBinding, NgModule } from '@angular/core'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class LazyImageDirective { /** * @param {?} el */ constructor(el) { this.el = el; this.willLoad = new EventEmitter(); this.decodingAttr = 'async'; } /** * @return {?} */ get visibilityStyle() { return this.srcAttr ? 'visible' : 'hidden'; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.src && changes.src.currentValue) { this.addIO(); } } /** * @return {?} */ ngOnDestroy() { if (this.io) { this.removeIO(); } } /** * @private * @return {?} */ canLazyLoad() { return typeof window !== 'undefined' && 'IntersectionObserver' in window; } /** * @private * @return {?} */ load() { this.srcAttr = this.src; this.willLoad.emit(); } /** * @private * @return {?} */ lazyLoadImage() { // Remove any previous observer if exists if (this.io) { this.removeIO(); } this.io = new IntersectionObserver((/** * @param {?} entry * @return {?} */ entry => { // because there will only ever be one instance // of the element we are observing // we can just use entry[0] if (entry[0].isIntersecting) { this.load(); this.removeIO(); } }), { root: this.root, rootMargin: this.rootMargin, threshold: this.threshold }); this.io.observe(this.el.nativeElement); } /** * @private * @return {?} */ loadImage() { setTimeout((/** * @return {?} */ () => this.load()), 200); } /** * @private * @return {?} */ addIO() { // Check if window is defined to handle SSR, as well as check for IntersectionObserever support in the browser if (this.canLazyLoad()) { this.lazyLoadImage(); } else { // Fallback to setTimeout if IntersectionObserver-based lazy loading is not supported this.loadImage(); } } /** * @private * @return {?} */ removeIO() { this.io.disconnect(); this.io = null; } } LazyImageDirective.decorators = [ { type: Directive, args: [{ selector: 'img[lazy]' },] } ]; /** @nocollapse */ LazyImageDirective.ctorParameters = () => [ { type: ElementRef } ]; LazyImageDirective.propDecorators = { src: [{ type: Input }], root: [{ type: Input }], rootMargin: [{ type: Input }], threshold: [{ type: Input }], willLoad: [{ type: Output }], srcAttr: [{ type: HostBinding, args: ['attr.src',] }], decodingAttr: [{ type: HostBinding, args: ['attr.decoding',] }], visibilityStyle: [{ type: HostBinding, args: ['style.visibility',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class LazyImageModule { } LazyImageModule.decorators = [ { type: NgModule, args: [{ declarations: [LazyImageDirective], exports: [LazyImageDirective] },] } ]; export { LazyImageDirective, LazyImageModule }; //# sourceMappingURL=trendster-io-ng-lazy-image.js.map