rabbit-simple-ui
Version:
A simple UI component library based on JavaScript
114 lines (89 loc) • 3.79 kB
text/typescript
import { $el, bind, getNumTypeAttr, removeAttrs, setCss, setHtml } from '../../dom-utils';
import PREFIX from '../prefix';
class BackTop {
readonly VERSION: string;
readonly COMPONENTS: NodeListOf<Element>;
constructor() {
this.VERSION = 'v1.0';
this.COMPONENTS = $el('r-back-top', { all: true });
this._create(this.COMPONENTS);
}
private _create(COMPONENTS: NodeListOf<Element>): void {
COMPONENTS.forEach((node) => {
const { right, bottom, height, duration } = this._attrs(node);
this._setRight(node, right);
this._setBottom(node, bottom);
this._setAppearance(node);
this._handleScroll(node, height);
this._handleClick(node, duration);
removeAttrs(node, ['right', 'bottom', 'height', 'duration']);
});
}
private _setRight(node: Element, right: number): void {
setCss(node, 'right', `${right}px`);
}
private _setBottom(node: Element, bottom: number): void {
setCss(node, 'bottom', `${bottom}px`);
}
private _setAppearance(node: Element): void {
if (setHtml(node) && setHtml(node) !== ' ') {
setHtml(node, node.innerHTML);
} else {
const template = `<div class="${PREFIX.backtop}-inner">
<i class="${PREFIX.icon} ${PREFIX.icon}-ios-arrow-up"></i>
</div>`;
setHtml(node, template);
}
}
private _handleScroll(node: Element, height: number): void {
const visable = (y: number) => {
const scrollY = Math.floor(y);
const visibilityHeight = Math.floor(height);
// 判断页面是否滚动到指定显示的高度
scrollY >= visibilityHeight
? setCss(node, 'display', 'block')
: setCss(node, 'display', '');
};
bind(window, 'scroll', () => {
visable(window.scrollY);
});
}
private _handleClick(node: Element, duration: number): void {
bind(node, 'click', () => {
const sTop: number = document.documentElement.scrollTop || document.body.scrollTop;
this._scrollTop(window, sTop, 0, duration);
});
}
private _scrollTop(el: any, from: number, to: number, duration: number) {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame =
window.webkitRequestAnimationFrame ||
// @ts-ignore
window.mozRequestAnimationFrame ||
// @ts-ignore
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000 / 60);
};
}
const difference = Math.abs(from - to);
const step = Math.ceil((difference / duration) * 25);
const scroll = (start: number, end: number, step: number) => {
let d = start + step > end ? end : start + step;
if (start <= end && d == 0) return;
d = start - step < end ? end : start - step;
el === window ? window.scrollTo(d, d) : (el.scrollTop = d);
window.requestAnimationFrame(() => scroll(d, end, step));
};
scroll(from, to, step);
}
private _attrs(node: Element) {
return {
right: getNumTypeAttr(node, 'right', 30),
bottom: getNumTypeAttr(node, 'bottom', 30),
height: getNumTypeAttr(node, 'height', 400),
duration: getNumTypeAttr(node, 'duration', 500)
};
}
}
export default BackTop;