@greg-md/ng-lazy-load
Version:
Lazy loading images with Angular.
338 lines (332 loc) • 9.65 kB
JavaScript
import { Directive, ElementRef, HostBinding, Inject, Input, NgModule, PLATFORM_ID, Renderer2 } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @param {?} element
* @return {?}
*/
function offset(element) {
// Support: IE <=11 only
// Running getBoundingClientRect on a
// disconnected node in IE throws an error
if (!element || !element.getClientRects().length) {
return { top: 0, left: 0 };
}
var /** @type {?} */ docElem, /** @type {?} */ rect, /** @type {?} */ doc;
rect = element.getBoundingClientRect();
// Make sure element is not hidden (display: none)
if (rect.width || rect.height) {
doc = element.ownerDocument;
docElem = doc.documentElement;
return {
top: rect.top + window.pageYOffset - docElem.clientTop,
left: rect.left + window.pageXOffset - docElem.clientLeft
};
}
// Return zeros for disconnected and hidden elements (gh-2310)
return rect;
}
/**
* @record
*/
/**
* @param {?} element
* @param {?=} settings
* @return {?}
*/
function aboveTheTop(element, settings) {
if (settings === void 0) { settings = {}; }
if (!element) {
return false;
}
var /** @type {?} */ fold, /** @type {?} */
container = settings.container || window, /** @type {?} */
threshold = settings.threshold || 0;
if (container instanceof HTMLElement) {
fold = offset(container).top;
}
else {
fold = window.scrollY;
}
return fold >= (offset(element).top + threshold + element.offsetHeight);
}
/**
* @param {?} element
* @param {?=} settings
* @return {?}
*/
function rightOfFold(element, settings) {
if (settings === void 0) { settings = {}; }
if (!element) {
return false;
}
var /** @type {?} */ fold, /** @type {?} */
container = settings.container || window, /** @type {?} */
threshold = settings.threshold || 0;
if (container instanceof HTMLElement) {
fold = offset(container).left + container.offsetWidth;
}
else {
fold = window.innerWidth + window.scrollX;
}
return fold <= offset(element).left - threshold;
}
/**
* @param {?} element
* @param {?=} settings
* @return {?}
*/
function belowTheFold(element, settings) {
if (settings === void 0) { settings = {}; }
if (!element) {
return false;
}
var /** @type {?} */ fold, /** @type {?} */
container = settings.container || window, /** @type {?} */
threshold = settings.threshold || 0;
if (container instanceof HTMLElement) {
fold = offset(container).top + container.offsetHeight;
}
else {
fold = window.innerHeight + window.scrollY;
}
return fold <= offset(element).top - threshold;
}
/**
* @param {?} element
* @param {?=} settings
* @return {?}
*/
function leftOfBegin(element, settings) {
if (settings === void 0) { settings = {}; }
if (!element) {
return false;
}
var /** @type {?} */ fold, /** @type {?} */
container = settings.container || window, /** @type {?} */
threshold = settings.threshold || 0;
if (container instanceof HTMLElement) {
fold = offset(container).left;
}
else {
fold = window.scrollX;
}
return fold >= offset(element).left + threshold + element.offsetWidth;
}
/**
* @param {?} element
* @param {?=} settings
* @return {?}
*/
function inViewport(element, settings) {
if (settings === void 0) { settings = {}; }
return !belowTheFold(element, settings)
&& !aboveTheTop(element, settings)
&& !leftOfBegin(element, settings)
&& !rightOfFold(element, settings);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var LazyLoadDirective = (function () {
function LazyLoadDirective(elementRef, renderer, platformId) {
this.elementRef = elementRef;
this.renderer = renderer;
this.platformId = platformId;
this.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
this._threshold = 0;
}
Object.defineProperty(LazyLoadDirective.prototype, "threshold", {
set: /**
* @param {?} position
* @return {?}
*/
function (position) {
this._threshold = parseInt(this.threshold + '', 10);
},
enumerable: true,
configurable: true
});
Object.defineProperty(LazyLoadDirective.prototype, "thresold", {
get: /**
* @return {?}
*/
function () {
return this._threshold;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
LazyLoadDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.initBgSrc();
this.initEvents();
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.ngAfterContentInit = /**
* @return {?}
*/
function () {
this.tryLoading();
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.unloadListeners();
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.initBgSrc = /**
* @return {?}
*/
function () {
if (this.bgSrc) {
this.backgroundImage = 'url(' + this.bgSrc + ')';
this.backgroundPosition = 'center center';
this.backgroundSize = 'cover';
}
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.initEvents = /**
* @return {?}
*/
function () {
var _this = this;
this.scrollUnload = this.renderer.listen('window', 'scroll', function () {
_this.tryLoading();
});
if (this.container) {
this.containerScrollUnload = this.renderer.listen(this.container, 'scroll', function () {
_this.tryLoading();
});
}
this.resizeUnload = this.renderer.listen('window', 'resize', function () {
_this.tryLoading();
});
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.tryLoading = /**
* @return {?}
*/
function () {
if (!isPlatformBrowser(this.platformId)) {
return;
}
if (this.container && inViewport(this.container, { threshold: this.threshold })) {
this.tryImgLoading();
}
else if (!this.container) {
this.tryImgLoading();
}
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.tryImgLoading = /**
* @return {?}
*/
function () {
var /** @type {?} */ inWindowViewport = this.container ? inViewport(this.elementRef.nativeElement, { threshold: this.threshold }) : false;
var /** @type {?} */ inContainerViewport = inViewport(this.elementRef.nativeElement, { threshold: this.threshold, container: this.container });
if (inWindowViewport && inContainerViewport) {
console.log('in viewport', this.container);
this.load();
this.unloadListeners();
}
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.load = /**
* @return {?}
*/
function () {
var _this = this;
if (this.bgSrc) {
this.src = this.lazySrc;
}
else {
var /** @type {?} */ img = this.renderer.createElement('img');
img.onload = function () {
_this.src = _this.lazySrc;
};
img.src = this.lazySrc;
}
};
/**
* @return {?}
*/
LazyLoadDirective.prototype.unloadListeners = /**
* @return {?}
*/
function () {
if (this.scrollUnload) {
this.scrollUnload();
}
if (this.containerScrollUnload) {
this.containerScrollUnload();
}
if (this.resizeUnload) {
this.resizeUnload();
}
};
LazyLoadDirective.decorators = [
{ type: Directive, args: [{
selector: 'img[lazy-load]',
},] },
];
/** @nocollapse */
LazyLoadDirective.ctorParameters = function () { return [
{ type: ElementRef, },
{ type: Renderer2, },
{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] },
]; };
LazyLoadDirective.propDecorators = {
"src": [{ type: HostBinding, args: ['src',] }, { type: Input },],
"backgroundImage": [{ type: HostBinding, args: ['style.background-image',] },],
"backgroundPosition": [{ type: HostBinding, args: ['style.background-position',] },],
"backgroundSize": [{ type: HostBinding, args: ['style.background-size',] },],
"lazySrc": [{ type: Input, args: ['lazy-load',] },],
"bgSrc": [{ type: Input, args: ['bg-src',] },],
"threshold": [{ type: Input },],
"container": [{ type: Input },],
};
return LazyLoadDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var LazyLoadModule = (function () {
function LazyLoadModule() {
}
LazyLoadModule.decorators = [
{ type: NgModule, args: [{
imports: [],
declarations: [LazyLoadDirective],
exports: [LazyLoadDirective]
},] },
];
return LazyLoadModule;
}());
export { LazyLoadModule, LazyLoadDirective };