@duoduo-oba/ng-devui
Version:
DevUI components based on Angular
405 lines (399 loc) • 15.1 kB
JavaScript
import { EventEmitter, Component, ElementRef, HostBinding, Input, Output, ViewChild, HostListener, NgModule } from '@angular/core';
/**
* @fileoverview added by tsickle
* Generated from: sticky.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var StickyComponent = /** @class */ (function () {
function StickyComponent(el) {
var _this = this;
this.el = el;
this.hostPosition = 'relative';
this.statusChange = new EventEmitter();
this._prevStatus = undefined;
this._status = 'normal';
// 用于监听是否是横向滚动
this.THROTTLE_DELAY = 16;
this.THROTTLE_TRIGGER = 100;
this.throttle = (/**
* @return {?}
*/
function () {
/** @type {?} */
var fn = _this.scrollAndResizeHock;
/** @type {?} */
var time = Date.now();
if (_this.scrollTimer) {
clearTimeout(_this.scrollTimer);
}
if (!_this.scrollPreStart) {
_this.scrollPreStart = time;
}
if (time - _this.scrollPreStart > _this.THROTTLE_TRIGGER) {
fn();
_this.scrollPreStart = null;
_this.scrollTimer = null;
}
else {
_this.scrollTimer = setTimeout((/**
* @return {?}
*/
function () {
fn();
_this.scrollPreStart = null;
_this.scrollTimer = null;
}), _this.THROTTLE_DELAY);
}
});
this.scrollAndResizeHock = (/**
* @return {?}
*/
function () {
if (_this.container.getBoundingClientRect().left - (_this.containerLeft || 0) !== 0) {
_this.status = 'stay';
_this.containerLeft = _this.container.getBoundingClientRect().left;
}
else {
_this.scrollHandler();
}
});
this.scrollHandler = (/**
* @return {?}
*/
function () {
/** @type {?} */
var computedStyle = window.getComputedStyle(_this.container);
if (_this.parentNode.getBoundingClientRect().top > (_this.view && _this.view.top || 0)) {
_this.status = 'normal'; // 全局滑动(container!==parentNode)时候增加预判
}
else if (_this.container.getBoundingClientRect().top
+ parseInt(computedStyle.paddingTop, 10)
+ parseInt(computedStyle.borderTopWidth, 10)
>= (_this.view && _this.view.top || 0)) {
_this.status = 'normal';
}
else if (_this.container.getBoundingClientRect().bottom
- parseInt(computedStyle.paddingBottom, 10)
- parseInt(computedStyle.borderBottomWidth, 10)
- _this.wrapper.nativeElement.getBoundingClientRect().height
< (_this.view && _this.view.top || 0) + (_this.view && _this.view.bottom || 0)) {
_this.status = 'remain';
}
else if ((_this.container.getBoundingClientRect().top + parseInt(computedStyle.paddingTop, 10) < (_this.view && _this.view.top || 0))) {
_this.status = 'follow';
}
});
}
Object.defineProperty(StickyComponent.prototype, "status", {
get: /**
* @return {?}
*/
function () {
return this._status;
},
set: /**
* @param {?} status
* @return {?}
*/
function (status) {
if (status !== this._status) {
this._prevStatus = this._status;
this._status = status;
this.statusProcess(this._status);
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
StickyComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.parentNode = this.el.nativeElement.parentNode;
if (!this.container) {
this.container = this.parentNode;
}
};
/**
* @return {?}
*/
StickyComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
this.scrollTarget = this.scrollTarget || window; // window有scroll事件,document.documentElement没有scroll事件
this.scrollTarget.addEventListener('scroll', this.throttle);
this.initScrollStatus(this.scrollTarget);
};
/**
* @return {?}
*/
StickyComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.scrollTarget.removeEventListener('scroll', this.throttle);
};
/**
* @param {?} status
* @return {?}
*/
StickyComponent.prototype.statusProcess = /**
* @param {?} status
* @return {?}
*/
function (status) {
switch (status) {
case 'normal':
this.wrapper.nativeElement.style.top = 'auto';
this.wrapper.nativeElement.style.left = 'auto';
this.wrapper.nativeElement.style.position = 'static';
break;
case 'follow':
this.wrapper.nativeElement.style.top = (this.view && this.view.top || 0) + 'px';
this.wrapper.nativeElement.style.left = this.wrapper.nativeElement.getBoundingClientRect().left + 'px';
this.wrapper.nativeElement.style.position = 'fixed';
break;
case 'stay':
this.wrapper.nativeElement.style.top =
this.calculateRelativePosition(this.wrapper.nativeElement, this.parentNode, 'top') + 'px';
this.wrapper.nativeElement.style.left = 'auto';
this.wrapper.nativeElement.style.position = 'relative';
break;
case 'remain':
if (this.wrapper.nativeElement.style.position !== 'fixed' || this.wrapper.nativeElement.style.position !== 'absolute') {
this.wrapper.nativeElement.style.top =
this.calculateRelativePosition(this.wrapper.nativeElement, this.parentNode, 'top') + 'px';
this.wrapper.nativeElement.style.left = 'auto';
this.wrapper.nativeElement.style.position = 'absolute'; // 要先转为absolute再计算,否则如果处于非fixed影响计算
}
this.wrapper.nativeElement.style.top =
this.calculateRemainPosition(this.wrapper.nativeElement, this.parentNode, this.container) + 'px';
this.wrapper.nativeElement.style.left =
this.calculateRelativePosition(this.wrapper.nativeElement, this.parentNode, 'left') + 'px';
this.wrapper.nativeElement.style.position = 'relative';
break;
default:
break;
}
};
/**
* @param {?} element
* @param {?} relativeElement
* @param {?} direction
* @return {?}
*/
StickyComponent.prototype.calculateRelativePosition = /**
* @param {?} element
* @param {?} relativeElement
* @param {?} direction
* @return {?}
*/
function (element, relativeElement, direction) {
/** @type {?} */
var key = {
'left': ['left', 'Left'],
'top': ['top', 'Top']
};
if (window && window.getComputedStyle) {
/** @type {?} */
var computedStyle = window.getComputedStyle(relativeElement);
return element.getBoundingClientRect()[key[direction][0]]
- relativeElement.getBoundingClientRect()[key[direction][0]]
- parseInt(computedStyle['padding' + key[direction][1]], 10)
- parseInt(computedStyle['border' + key[direction][1] + 'Width'], 10);
}
};
/**
* @param {?} element
* @param {?} relativeElement
* @param {?} container
* @return {?}
*/
StickyComponent.prototype.calculateRemainPosition = /**
* @param {?} element
* @param {?} relativeElement
* @param {?} container
* @return {?}
*/
function (element, relativeElement, container) {
if (window && window.getComputedStyle) {
/** @type {?} */
var computedStyle = window.getComputedStyle(container);
/** @type {?} */
var result = container.getBoundingClientRect().height
- element.getBoundingClientRect().height
+ container.getBoundingClientRect().top
- relativeElement.getBoundingClientRect().top
- parseInt(computedStyle['paddingTop'], 10)
- parseInt(computedStyle['borderTopWidth'], 10)
- parseInt(computedStyle['paddingBottom'], 10)
- parseInt(computedStyle['borderBottomWidth'], 10);
return result < 0 ? 0 : result;
}
};
/**
* @param {?} target
* @return {?}
*/
StickyComponent.prototype.initScrollStatus = /**
* @param {?} target
* @return {?}
*/
function (target) {
/** @type {?} */
var scrollTargets = target === window ? [document.documentElement, document.body] : [target];
/** @type {?} */
var flag = false;
scrollTargets.forEach((/**
* @param {?} scrollTarget
* @return {?}
*/
function (scrollTarget) {
if (scrollTarget.scrollTop && scrollTarget.scrollTop > 0) {
flag = true;
}
}));
if (flag) {
setTimeout(this.scrollHandler);
}
};
/**
* 提供给业务自己触发
* 用法:
* 1.捕获所有sticky:```@ViewChildren(StickyComponent) stickies;```
* 2.触发刷新:当需要手动触发更新的时候,比如订阅数据返回后页面高度发生变化可以调用 ```stickies.forEach(sticky => sticky.recalculatePosition());```
* 慎用,少用, 使用太多会影响性能。
*/
/**
* 提供给业务自己触发
* 用法:
* 1.捕获所有sticky:```\@ViewChildren(StickyComponent) stickies;```
* 2.触发刷新:当需要手动触发更新的时候,比如订阅数据返回后页面高度发生变化可以调用 ```stickies.forEach(sticky => sticky.recalculatePosition());```
* 慎用,少用, 使用太多会影响性能。
* @return {?}
*/
StickyComponent.prototype.recalculatePosition = /**
* 提供给业务自己触发
* 用法:
* 1.捕获所有sticky:```\@ViewChildren(StickyComponent) stickies;```
* 2.触发刷新:当需要手动触发更新的时候,比如订阅数据返回后页面高度发生变化可以调用 ```stickies.forEach(sticky => sticky.recalculatePosition());```
* 慎用,少用, 使用太多会影响性能。
* @return {?}
*/
function () {
this.initScrollStatus(this.scrollTarget);
};
StickyComponent.decorators = [
{ type: Component, args: [{
selector: 'd-sticky',
template: "\n <div #stickyWrapper [style.zIndex]=\"zIndex\">\n <ng-content></ng-content>\n </div>\n "
}] }
];
/** @nocollapse */
StickyComponent.ctorParameters = function () { return [
{ type: ElementRef }
]; };
StickyComponent.propDecorators = {
hostPosition: [{ type: HostBinding, args: ['style.position',] }],
zIndex: [{ type: Input }],
container: [{ type: Input }],
view: [{ type: Input }],
scrollTarget: [{ type: Input }],
statusChange: [{ type: Output }],
wrapper: [{ type: ViewChild, args: ['stickyWrapper', { static: true },] }],
throttle: [{ type: HostListener, args: ['window:resize',] }]
};
return StickyComponent;
}());
if (false) {
/** @type {?} */
StickyComponent.prototype.hostPosition;
/** @type {?} */
StickyComponent.prototype.zIndex;
/** @type {?} */
StickyComponent.prototype.container;
/** @type {?} */
StickyComponent.prototype.view;
/** @type {?} */
StickyComponent.prototype.scrollTarget;
/** @type {?} */
StickyComponent.prototype.statusChange;
/** @type {?} */
StickyComponent.prototype.wrapper;
/** @type {?} */
StickyComponent.prototype._prevStatus;
/** @type {?} */
StickyComponent.prototype._status;
/** @type {?} */
StickyComponent.prototype.parentNode;
/** @type {?} */
StickyComponent.prototype.containerLeft;
/**
* @type {?}
* @private
*/
StickyComponent.prototype.THROTTLE_DELAY;
/**
* @type {?}
* @private
*/
StickyComponent.prototype.THROTTLE_TRIGGER;
/**
* @type {?}
* @private
*/
StickyComponent.prototype.scrollPreStart;
/**
* @type {?}
* @private
*/
StickyComponent.prototype.scrollTimer;
/** @type {?} */
StickyComponent.prototype.throttle;
/** @type {?} */
StickyComponent.prototype.scrollAndResizeHock;
/** @type {?} */
StickyComponent.prototype.scrollHandler;
/**
* @type {?}
* @private
*/
StickyComponent.prototype.el;
}
/**
* @fileoverview added by tsickle
* Generated from: sticky.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var StickyModule = /** @class */ (function () {
function StickyModule() {
}
StickyModule.decorators = [
{ type: NgModule, args: [{
imports: [],
declarations: [
StickyComponent
],
exports: [
StickyComponent,
],
},] }
];
return StickyModule;
}());
/**
* @fileoverview added by tsickle
* Generated from: public-api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: ng-devui-sticky.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { StickyComponent, StickyModule };
//# sourceMappingURL=ng-devui-sticky.js.map