2017-03-23 1 views
0

J'ai le modèle angular2 suivant:cliquez événement éviter à long presse

<div (click)="foo()"> 
    <img (longPress)="bar(1)" (click)="foobar(1)" /> 
    <img (longPress)="bar(2)" (click)="foobar(2)"/> 
</div> 

Longpress est une directive attribut personnalisé qui se déclenche lorsque vous avez un mousedown pendant 500 ms.

Cliquez sur les événements sur le <div> et <img> sont gérées très bien. Lorsque je fais un longpress sur une image, la fonction bar() est appelée. Cependant, à mouseUp (après un longpress) les événements de clic sont déclenchés sur le <img> et le parent <div>.

Comment puis-je empêcher ces clics de la manière la plus simple? Tout ce que je peux penser maintenant est d'écrire une directive d'attribut personnalisée qui ne se déclenche que sur des "clics" qui prennent moins de 500 ms. Cela semble juste un peu exagéré pour moi.

Répondre

0

Je fini par créer un "Longpress" et une directive "shortPress". Le longpress se déclenche uniquement après un certain temps et les shortpres se déclenchent uniquement en dessous du même seuil.

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') onMouseLeave(e) { 
     if (this._isShort) { 
      this.shortPress.emit(e); 
     } 
     clearTimeout(this._timeout); 
    } 

    @HostListener('mouseleave') onMouseUp() { 
     clearTimeout(this._timeout); 
    } 
} 

et

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') onMouseLeave() { 
     clearTimeout(this._timeout); 
    } 

    @HostListener('mouseleave') onMouseUp() { 
     clearTimeout(this._timeout); 
    } 
} 
0

Avez-vous essayé de passer en $event comme premier paramètre, puis de faire un event.stopPropagation() dans votre méthode bar()? Quelque chose comme ceci:

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

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

+0

Je ne pensais d'une construction comme ça, mais cela signifie que je dois modifier les fonctions qui sont appelées. Je préfère avoir la solution dans la directive d'attribut elle-même afin qu'elle n'ait pas besoin d'un format spécifique pour que les fonctions qui lui sont transmises fonctionnent. En outre, le longpress renvoie un événement mousedown. Je ne suis pas sûr si l'arrêt d'un mousedown empêche le déclenchement d'un clic. – JasperZelf