我正在尝试制作一个非常轻量级和简单的懒惰滚动指令。我想这样使用它:
<some-element lazyScroll [lazyScrollDistance]="100" (lazyScrollAction)="loadMore()">...</some-element>
lazyScrollDistance
是用户必须从元素顶部向下滑动以启动lazyScrollAction
的像素数量。这将在随后的每100个像素中触发,但在向后时不会重复。
我编写的代码实现了这一点,但有一点需要注意:滚动事件不会被激发1,2,3,4,5,6等像素,而是被触发(取决于我滚动的速度)分块,如1,4,10,13,15等。
这打破了我的逻辑,因为我期望卷轴在100%的时间内增加一倍。
有人可以就此提出建议吗?
以下是代码:
import { Directive, Input, Output, EventEmitter, ElementRef } from '@angular/core';
import { WindowRefService } from 'core/services/window-ref/window-ref.service';
interface HitMap {
[position: number]: boolean;
}
@Directive({
selector: '[lazyScroll]',
})
export class LazyScrollDirective {
private hitMap: HitMap = {};
@Input('lazyScrollDistance') scrollDistance = 100;
@Output() lazyScrollAction: EventEmitter<any> = new EventEmitter();
constructor(
private windowRef: WindowRefService,
private element: ElementRef,
) {
const win = windowRef.nativeWindow;
const el = element.nativeElement;
document.addEventListener('scroll', () => {
this.onScroll(win, el);
});
}
onScroll(win: Window, el: any) {
const currentPos = win.pageYOffset;
if (this.hitMap[currentPos]) {
return;
}
const elementTopRelativeToViewport = el.getBoundingClientRect().top;
const elementTopRelativeToDocument = elementTopRelativeToViewport + currentPos;
const startBase = elementTopRelativeToDocument + this.scrollDistance;
if (currentPos > startBase && currentPos % this.scrollDistance === 0) {
this.hitMap[currentPos] = true;
this.lazyScrollAction.emit(null);
}
}
}
这是WindowRefService
:
import { Injectable } from '@angular/core';
function getWindow(): any {
return window;
}
@Injectable()
export class WindowRefService {
get nativeWindow(): any {
return getWindow();
}
}