Created
March 15, 2021 10:35
-
-
Save lydemann/b901fbd81c90fc1d6b946beb41cd87a9 to your computer and use it in GitHub Desktop.
prevent-ghost-clicks.directive.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive, ElementRef, HostListener, OnInit } from '@angular/core'; | |
import 'hammerjs'; | |
/* | |
Preventing clicks after a HammerJS press (long press) event. | |
Inspired from HammerJS ghost click helper: https://gist.github.com/jtangelder/361052976f044200ea17 | |
*/ | |
@Directive({ | |
selector: '[preventGhostClicks]', | |
}) | |
export class PreventGhostClicksDirective implements OnInit { | |
// coordinates for preventing clicks | |
coordinates: [number, number][] = []; | |
// threshold for click prevented area | |
threshold = 25; | |
// timeout for resetting click prevention coordinates | |
timeout = 50; | |
constructor(private elementRef: ElementRef) {} | |
ngOnInit(): void { | |
const el = this.elementRef.nativeElement; | |
// rneeds to set useCapure true to prevent click in case of ghost click | |
el.addEventListener( | |
'click', | |
this.preventClickIfGhostClick.bind(this), | |
true | |
); | |
} | |
/** | |
* prevent clicks if they're in a registered XY region | |
* @param {MouseEvent} ev | |
*/ | |
preventClickIfGhostClick(ev) { | |
for (var i = 0; i < this.coordinates.length; i++) { | |
var x = this.coordinates[i][0]; | |
var y = this.coordinates[i][1]; | |
// within the range, so prevent the click | |
if ( | |
Math.abs(ev.clientX - x) < this.threshold && | |
Math.abs(ev.clientY - y) < this.threshold | |
) { | |
ev.stopPropagation(); | |
ev.preventDefault(); | |
break; | |
} | |
} | |
} | |
@HostListener('press') | |
resetCoordinates() { | |
this.coordinates = []; | |
} | |
/** | |
* remove the first coordinates set from the array | |
*/ | |
popCoordinates() { | |
this.coordinates.splice(0, 1); | |
} | |
/** | |
* if it is a pressup, we want to register it's place | |
* @param {TouchEvent} ev | |
*/ | |
@HostListener('pressup', ['$event']) | |
registerCoordinates(ev) { | |
var click = ev.pointers[0]; | |
this.coordinates.push([click.clientX, click.clientY]); | |
setTimeout(this.popCoordinates.bind(this), this.timeout); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment