UNPKG

@trendster-io/ng-lazy-image

Version:

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

195 lines 11.2 kB
/** * @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