Skip to content

Instantly share code, notes, and snippets.

@lydemann
Created March 15, 2021 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lydemann/b901fbd81c90fc1d6b946beb41cd87a9 to your computer and use it in GitHub Desktop.
Save lydemann/b901fbd81c90fc1d6b946beb41cd87a9 to your computer and use it in GitHub Desktop.
prevent-ghost-clicks.directive.ts
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