Reputation: 772
I'm using @HostListener scroll event for angular, and I'm hoping to find a way that I can get it to wait 3 seconds before it does anything, but only the first time it is triggered
@HostListener('window:scroll', ['$event']) getScrollHeight(event) {
const numberWhenItEntersViewport =
document.getElementById("innerScreenSection").offsetTop -
document.documentElement.clientHeight;
const yValueBottomOfElement =
document.getElementById("innerScreenSection").offsetTop +
document.getElementById("innerScreenSection").offsetHeight;
const elementHeight = document.getElementById("innerScreenSection")
.offsetHeight;
// if the element is where I want it and the timer has not gone yet then start the timer
// I realize I never declare waitedThreeSeconds, this is just for show of what I'm thinking
if (
waitedThreeSeconds === false &&
window.pageYOffset >= numberWhenItEntersViewport + 0.25 * elementHeight &&
window.pageYOffset <= yValueBottomOfElement - 0.3 * elementHeight
) {
// start timer and set waitedThreeSeconds to true? Idk how to do this without declaring
// a varible in here and having it turned back to false everytime this function is called
// it also does not seem to be able to read variables outside of this function
// specifically when they change it doesnt update
} else {
// 3 seconds have passed
console.log("scrolling and 3 seconds have passed");
}
}
Upvotes: 1
Views: 2056
Reputation: 815
import { Subject, Observable } from 'rxjs';
import { delay, concatMap } from 'rxjs/operators';
// Delay amount (ms)
const DELAY = 3000;
...
// Setup
private readonly eventStream = new Subject<Event>();
// On the first emission, delay.
// After the delay, REMAP to the original stream (concatMap)
// USE first() to complete outer observable.
get eventStream$(): Observable<Event> {
return this.eventStream.pipe(
delay(DELAY),
first(),
concatMap(() => this.eventStream)
);
}
// Listen to clicks and emit
@HostListener('window:scroll', ['$event']) scroll(event: Event) {
this.eventStream.next(event);
}
constructor() {
this.eventStream$.subscribe(this.isScroll);
}
isScroll(event: Event) {
// Do math here.
console.log(event);
}
ngOnDestroy() {
// Cleanup.
this.eventStream.unsubscribe();
}
Now we could proceed to throttle responses etc.
Upvotes: 4
Reputation: 391
You may try something like below snippet. Hope it may help you.
timeOutId:number;
@HostListener('window:scroll', ['$event']) getScrollHeight(event) {
clearTimeout(this.timeOutId);
this.timeoutId = setTimeout(() => {
// call your method
}, 3000);
}
Upvotes: 2