@trendster-io/ng-lazy-image
Version:
An Angular directive to efficiently lazy load images using the IntersectionObserver API.
188 lines (184 loc) • 5 kB
JavaScript
import { Directive, ElementRef, Input, Output, HostBinding, EventEmitter, NgModule } from '@angular/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var LazyImageDirective = /** @class */ (function () {
function LazyImageDirective(el) {
this.el = el;
this.willLoad = new EventEmitter();
this.decodingAttr = 'async';
}
Object.defineProperty(LazyImageDirective.prototype, "visibilityStyle", {
get: /**
* @return {?}
*/
function () {
return this.srcAttr ? 'visible' : 'hidden';
},
enumerable: true,
configurable: true
});
/**
* @param {?} changes
* @return {?}
*/
LazyImageDirective.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes.src && changes.src.currentValue) {
this.addIO();
}
};
/**
* @return {?}
*/
LazyImageDirective.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
if (this.io) {
this.removeIO();
}
};
/**
* @private
* @return {?}
*/
LazyImageDirective.prototype.canLazyLoad = /**
* @private
* @return {?}
*/
function () {
return typeof window !== 'undefined' && 'IntersectionObserver' in window;
};
/**
* @private
* @return {?}
*/
LazyImageDirective.prototype.load = /**
* @private
* @return {?}
*/
function () {
this.srcAttr = this.src;
this.willLoad.emit();
};
/**
* @private
* @return {?}
*/
LazyImageDirective.prototype.lazyLoadImage = /**
* @private
* @return {?}
*/
function () {
var _this = this;
// Remove any previous observer if exists
if (this.io) {
this.removeIO();
}
this.io = new IntersectionObserver((/**
* @param {?} entry
* @return {?}
*/
function (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 {?}
*/
LazyImageDirective.prototype.loadImage = /**
* @private
* @return {?}
*/
function () {
var _this = this;
setTimeout((/**
* @return {?}
*/
function () { return _this.load(); }), 200);
};
/**
* @private
* @return {?}
*/
LazyImageDirective.prototype.addIO = /**
* @private
* @return {?}
*/
function () {
// 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 {?}
*/
LazyImageDirective.prototype.removeIO = /**
* @private
* @return {?}
*/
function () {
this.io.disconnect();
this.io = null;
};
LazyImageDirective.decorators = [
{ type: Directive, args: [{
selector: 'img[lazy]'
},] }
];
/** @nocollapse */
LazyImageDirective.ctorParameters = function () { return [
{ 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',] }]
};
return LazyImageDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var LazyImageModule = /** @class */ (function () {
function LazyImageModule() {
}
LazyImageModule.decorators = [
{ type: NgModule, args: [{
declarations: [LazyImageDirective],
exports: [LazyImageDirective]
},] }
];
return LazyImageModule;
}());
export { LazyImageDirective, LazyImageModule };
//# sourceMappingURL=trendster-io-ng-lazy-image.js.map