'prevent click event on long press

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.



Solution 1:[1]

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);
    }
}

Solution 2:[2]

Have you tried passing in $event as the first parameter, and then do a event.stopPropagation() in your bar()-method? Something like this:

<img (longPress)="bar($event,1)" (click)="foobar(1)" />

function bar(event:Event,myNum:number){event.stopPropagation();}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 John