75 lines
1.7 KiB
TypeScript
75 lines
1.7 KiB
TypeScript
export type ScrollListener = {
|
|
|
|
source: Event;
|
|
viewWidth: number;
|
|
viewHeight: number;
|
|
top: number;
|
|
bottom: number;
|
|
}
|
|
|
|
export default class Scroller {
|
|
|
|
private static instance: Scroller;
|
|
|
|
listeners = new Map<string, Function>();
|
|
|
|
private constructor() {
|
|
|
|
window.addEventListener("scroll", source => {
|
|
// 滚动距离
|
|
const top = document.body.scrollTop || document.documentElement.scrollTop;
|
|
// 可视高度
|
|
const viewWidth = document.documentElement.clientWidth || document.body.clientWidth;
|
|
// 可视高度
|
|
const viewHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
// 滚动高度
|
|
const sH = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
// 触发事件
|
|
const bottom = sH - top - viewHeight;
|
|
this.listeners.forEach(listener => listener({
|
|
source,
|
|
viewWidth,
|
|
viewHeight,
|
|
top,
|
|
bottom
|
|
} as ScrollListener));
|
|
}, true);
|
|
}
|
|
|
|
private static getInstance(): Scroller {
|
|
if (!Scroller.instance) {
|
|
Scroller.instance = new Scroller();
|
|
}
|
|
return Scroller.instance;
|
|
}
|
|
|
|
/**
|
|
* 添加监听
|
|
*
|
|
* @param name 事件名
|
|
* @param listener 监听事件
|
|
*/
|
|
public static addListener(name: string, listener: (event: ScrollListener) => void) {
|
|
Scroller.getInstance().listeners.set(name, listener);
|
|
}
|
|
|
|
/**
|
|
* 移除监听
|
|
*
|
|
* @param name 事件名
|
|
*/
|
|
public static removeListener(name: string) {
|
|
Scroller.getInstance().listeners.delete(name);
|
|
}
|
|
|
|
/** 滚动至顶(平滑地) */
|
|
public static toTop() {
|
|
document.body.scrollIntoView({behavior: "smooth"});
|
|
}
|
|
|
|
/** 滚动至指定节点(平滑地) */
|
|
public static toElement(el: HTMLElement) {
|
|
el.scrollIntoView({behavior: "smooth"});
|
|
}
|
|
}
|