@trendster-io/ng-lazy-image
Version:
An Angular directive to efficiently lazy load images using the IntersectionObserver API.
195 lines • 11.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Directive, ElementRef, EventEmitter, HostBinding, Input, Output } from '@angular/core';
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;
}());
export { LazyImageDirective };
if (false) {
/**
* @type {?}
* @private
*/
LazyImageDirective.prototype.io;
/** @type {?} */
LazyImageDirective.prototype.src;
/** @type {?} */
LazyImageDirective.prototype.root;
/** @type {?} */
LazyImageDirective.prototype.rootMargin;
/** @type {?} */
LazyImageDirective.prototype.threshold;
/** @type {?} */
LazyImageDirective.prototype.willLoad;
/** @type {?} */
LazyImageDirective.prototype.srcAttr;
/** @type {?} */
LazyImageDirective.prototype.decodingAttr;
/**
* @type {?}
* @private
*/
LazyImageDirective.prototype.el;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF6eS1pbWFnZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdHJlbmRzdGVyLWlvL25nLWxhenktaW1hZ2UvIiwic291cmNlcyI6WyJsaWIvbGF6eS1pbWFnZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUdMLE1BQU0sRUFFUCxNQUFNLGVBQWUsQ0FBQztBQUV2QjtJQWdCRSw0QkFBb0IsRUFBdUI7UUFBdkIsT0FBRSxHQUFGLEVBQUUsQ0FBcUI7UUFQakMsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFFaEIsaUJBQVksR0FBRyxPQUFPLENBQUM7SUFLUCxDQUFDO0lBSi9DLHNCQUFxQywrQ0FBZTs7OztRQUFwRDtZQUNFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDN0MsQ0FBQzs7O09BQUE7Ozs7O0lBSUQsd0NBQVc7Ozs7SUFBWCxVQUFZLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRTtZQUMzQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDZDtJQUNILENBQUM7Ozs7SUFFRCx3Q0FBVzs7O0lBQVg7UUFDRSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDWCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDakI7SUFDSCxDQUFDOzs7OztJQUVPLHdDQUFXOzs7O0lBQW5CO1FBQ0UsT0FBTyxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksc0JBQXNCLElBQUksTUFBTSxDQUFDO0lBQzNFLENBQUM7Ozs7O0lBRU8saUNBQUk7Ozs7SUFBWjtRQUNFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3ZCLENBQUM7Ozs7O0lBRU8sMENBQWE7Ozs7SUFBckI7UUFBQSxpQkFzQkM7UUFyQkMseUNBQXlDO1FBQ3pDLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNYLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNqQjtRQUNELElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxvQkFBb0I7Ozs7UUFDaEMsVUFBQSxLQUFLO1lBQ0gsK0NBQStDO1lBQy9DLGtDQUFrQztZQUNsQywyQkFBMkI7WUFDM0IsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFO2dCQUMzQixLQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ1osS0FBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQ2pCO1FBQ0gsQ0FBQyxHQUNEO1lBQ0UsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztTQUMxQixDQUNGLENBQUM7UUFDRixJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7Ozs7O0lBRU8sc0NBQVM7Ozs7SUFBakI7UUFBQSxpQkFFQztRQURDLFVBQVU7OztRQUFDLGNBQU0sT0FBQSxLQUFJLENBQUMsSUFBSSxFQUFFLEVBQVgsQ0FBVyxHQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Ozs7O0lBRU8sa0NBQUs7Ozs7SUFBYjtRQUNFLDhHQUE4RztRQUM5RyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUN0QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDdEI7YUFBTTtZQUNMLHFGQUFxRjtZQUNyRixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDbEI7SUFDSCxDQUFDOzs7OztJQUVPLHFDQUFROzs7O0lBQWhCO1FBQ0UsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQztJQUNqQixDQUFDOztnQkFoRkYsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxXQUFXO2lCQUN0Qjs7OztnQkFaQyxVQUFVOzs7c0JBZVQsS0FBSzt1QkFDTCxLQUFLOzZCQUNMLEtBQUs7NEJBQ0wsS0FBSzsyQkFDTCxNQUFNOzBCQUNOLFdBQVcsU0FBQyxVQUFVOytCQUN0QixXQUFXLFNBQUMsZUFBZTtrQ0FDM0IsV0FBVyxTQUFDLGtCQUFrQjs7SUFxRWpDLHlCQUFDO0NBQUEsQUFqRkQsSUFpRkM7U0E5RVksa0JBQWtCOzs7Ozs7SUFDN0IsZ0NBQWlDOztJQUNqQyxpQ0FBcUI7O0lBQ3JCLGtDQUF1Qjs7SUFDdkIsd0NBQTRCOztJQUM1Qix1Q0FBc0M7O0lBQ3RDLHNDQUE4Qzs7SUFDOUMscUNBQXlDOztJQUN6QywwQ0FBcUQ7Ozs7O0lBS3pDLGdDQUErQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2ltZ1tsYXp5XSdcbn0pXG5leHBvcnQgY2xhc3MgTGF6eUltYWdlRGlyZWN0aXZlIGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGlvOiBJbnRlcnNlY3Rpb25PYnNlcnZlcjtcbiAgQElucHV0KCkgc3JjOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJvb3Q6IEVsZW1lbnQ7XG4gIEBJbnB1dCgpIHJvb3RNYXJnaW46IHN0cmluZztcbiAgQElucHV0KCkgdGhyZXNob2xkOiBudW1iZXIgfCBudW1iZXJbXTtcbiAgQE91dHB1dCgpIHdpbGxMb2FkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIuc3JjJykgc3JjQXR0cjogc3RyaW5nO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIuZGVjb2RpbmcnKSBkZWNvZGluZ0F0dHIgPSAnYXN5bmMnO1xuICBASG9zdEJpbmRpbmcoJ3N0eWxlLnZpc2liaWxpdHknKSBnZXQgdmlzaWJpbGl0eVN0eWxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3JjQXR0ciA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZjxFbGVtZW50Pikge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMuc3JjICYmIGNoYW5nZXMuc3JjLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy5hZGRJTygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlvKSB7XG4gICAgICB0aGlzLnJlbW92ZUlPKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYW5MYXp5TG9hZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ0ludGVyc2VjdGlvbk9ic2VydmVyJyBpbiB3aW5kb3c7XG4gIH1cblxuICBwcml2YXRlIGxvYWQoKTogdm9pZCB7XG4gICAgdGhpcy5zcmNBdHRyID0gdGhpcy5zcmM7XG4gICAgdGhpcy53aWxsTG9hZC5lbWl0KCk7XG4gIH1cblxuICBwcml2YXRlIGxhenlMb2FkSW1hZ2UoKTogdm9pZCB7XG4gICAgLy8gUmVtb3ZlIGFueSBwcmV2aW91cyBvYnNlcnZlciBpZiBleGlzdHNcbiAgICBpZiAodGhpcy5pbykge1xuICAgICAgdGhpcy5yZW1vdmVJTygpO1xuICAgIH1cbiAgICB0aGlzLmlvID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKFxuICAgICAgZW50cnkgPT4ge1xuICAgICAgICAvLyBiZWNhdXNlIHRoZXJlIHdpbGwgb25seSBldmVyIGJlIG9uZSBpbnN0YW5jZVxuICAgICAgICAvLyBvZiB0aGUgZWxlbWVudCB3ZSBhcmUgb2JzZXJ2aW5nXG4gICAgICAgIC8vIHdlIGNhbiBqdXN0IHVzZSBlbnRyeVswXVxuICAgICAgICBpZiAoZW50cnlbMF0uaXNJbnRlcnNlY3RpbmcpIHtcbiAgICAgICAgICB0aGlzLmxvYWQoKTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUlPKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHJvb3Q6IHRoaXMucm9vdCxcbiAgICAgICAgcm9vdE1hcmdpbjogdGhpcy5yb290TWFyZ2luLFxuICAgICAgICB0aHJlc2hvbGQ6IHRoaXMudGhyZXNob2xkXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmlvLm9ic2VydmUodGhpcy5lbC5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEltYWdlKCk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5sb2FkKCksIDIwMCk7XG4gIH1cblxuICBwcml2YXRlIGFkZElPKCk6IHZvaWQge1xuICAgIC8vIENoZWNrIGlmIHdpbmRvdyBpcyBkZWZpbmVkIHRvIGhhbmRsZSBTU1IsIGFzIHdlbGwgYXMgY2hlY2sgZm9yIEludGVyc2VjdGlvbk9ic2VyZXZlciBzdXBwb3J0IGluIHRoZSBicm93c2VyXG4gICAgaWYgKHRoaXMuY2FuTGF6eUxvYWQoKSkge1xuICAgICAgdGhpcy5sYXp5TG9hZEltYWdlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIHNldFRpbWVvdXQgaWYgSW50ZXJzZWN0aW9uT2JzZXJ2ZXItYmFzZWQgbGF6eSBsb2FkaW5nIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgIHRoaXMubG9hZEltYWdlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVJTygpOiB2b2lkIHtcbiAgICB0aGlzLmlvLmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLmlvID0gbnVsbDtcbiAgfVxufVxuIl19