I have the following angular2 template:
<div (click)="foo()">
<img (longPress)="bar(1)" (click)="foobar(1)" />
<img (longPress)="bar(2)" (click)="foobar(2)"/>
</div>
Longpress is a custom attribute directive that triggers when you have a mousedown for 500 ms.
Click events on the <div>
and <img>
are handled fine. When I do a longpress on an image, the bar() function is called. However, on mouseUp (after a longpress) the click events are triggered on the <img>
and the parent <div>
.
How can I prevent these click events in the simplest way.
Only thing I can think of now is to write a custom attribute directive that only triggers on "clicks" that take less than 500 ms. This just seems a bit over the top to me.
I ended up creating a "longPress" and a "shortPress" directive. The longpress only fires after a set amount of time and the shortpres only fires below that same threshold.
import { Directive, HostListener, Output, EventEmitter } from '@angular/core';
@Directive({ selector: '[shortPress]' })
export class ShortPressDirective {
@Output()
shortPress = new EventEmitter();
private _timeout: any;
private _isShort: boolean;
@HostListener('mousedown') onMouseDown( e ) {
this._isShort = true;
this._timeout = setTimeout(() => {
this._isShort = false;
}, 500);
}
@HostListener('mouseup') onMouseUp( e ) {
if (this._isShort) {
this.shortPress.emit( e );
}
clearTimeout(this._timeout);
}
@HostListener('mouseleave') onMouseLeave() {
clearTimeout(this._timeout);
}
}
and
import { Directive, HostListener, Output, EventEmitter } from '@angular/core';
@Directive({ selector: '[longPress]' })
export class LongPressDirective {
@Output()
longPress = new EventEmitter();
private _timeout: any;
@HostListener('mousedown') onMouseDown( e ) {
this._timeout = setTimeout(() => {
this.longPress.emit( e );
}, 500);
}
@HostListener('mouseup') onMouseUp() {
clearTimeout(this._timeout);
}
@HostListener('mouseleave') onMouseLeave() {
clearTimeout(this._timeout);
}
}