I created a simple click-and-hold directive that is supposed to send events when a user clicks-and-holds an element for some time. Here is the directive code:
import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
/**
Detects when the user clicks-and-holds a given element.
*/
@Directive({ selector: '[hold]' })
export class HoldDirective {
@Output('hold')
public holdEvent = new EventEmitter<null>();
@Input('holdDelay') holdDelay: number = 800;
@Input('holdRepeat') holdRepeat: number = 100;
interval: NodeJS.Timeout | null = null;
timeout: NodeJS.Timeout | null = null;
@HostListener('document:mousedown')
@HostListener('document:touchstart')
public onMouseDown(): void {
this.timeout = setTimeout(() => {
this.timeout = null;
this.interval = setInterval(() => {
this.holdEvent.next(null);
}, this.holdRepeat);
}, this.holdDelay);
}
@HostListener('document:mouseup')
@HostListener('document:touchend')
public onMouseUp(): void {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
return;
}
if (!this.interval) return;
clearInterval(this.interval);
this.interval = null;
}
}
What seems to be the problem with my code? Or is there another way of doing this?
It works just fine when there is only a single element that uses that directive, but whenever multiple elements use it, the event gets sent to every single one of them at the same time, even if the user is not holding that element.