防止自定义事件后触发点击事件

时间:2018-09-19 19:49:46

标签: javascript angular mouseevent dom-events

没有“ mousehold”事件,所以我写了一个:

import {
  Directive, Input, Output, EventEmitter, HostListener
} from '@angular/core';

@Directive({ selector: '[custMousehold]' })
export class MouseholdDirective {

  @Input() duration: number = 350; // ms
  @Output() mousehold: EventEmitter<any> = new EventEmitter();
  public timeout: NodeJS.Timer;

  @HostListener('mousedown', ['$event'])
  mousedown(event: MouseEvent) {
    if (event.which !== 1) return; // left mouse button only
    this.timeout = setTimeout(() => {
      this.mousehold.emit(event);
    }, this.duration);
  }

  @HostListener('mouseup')
  mouseup() { clearTimeout(this.timeout); }

}

这是我将其附加到元素上的方式:

<span custMousehold (mousehold)="do something ...

效果很好。但是我在同一元素上也有一个click事件:

<span custMousehold (mousehold)="do something" (click)="do something else ...

我希望click事件仅在mousehold没有触发时才触发。 我一直在尝试在整个代码中使用preventDefault()stopPropagation(),但是它们没有什么不同。 click始终会触发。

2 个答案:

答案 0 :(得分:1)

您可以过滤click事件以检查是否发出了mousehold。如果是这样,只需忽略click事件。

我正在提供plunkr来展示我的想法。主要问题与mouse up事件之前发出的click有关。我在上述指令中的mouseup监听器中做了一些小改动。

答案 1 :(得分:0)

我找到了一个行之有效的解决方案,虽然非常紧凑,但可能并不那么优雅。有人可能发布更好的。我所做的是将指令扩展了一点,以便向视图暴露一个布尔变量,该布尔变量告诉事件是否触发:

import {
  Directive, Input, Output, EventEmitter, HostListener
} from '@angular/core';

@Directive({ selector: '[custMousehold]', exportAs: 'custMousehold' })
export class MouseholdDirective {

  @Input() duration: number = 350; // ms
  @Output() mousehold: EventEmitter<any> = new EventEmitter();
  @Output() fired: boolean;
  public timeout: any;

  @HostListener('mousedown', ['$event'])
  mousedown(event: MouseEvent) {
    this.fired = false;
    if (event.which !== 1) return; // left mouse button only
    this.timeout = setTimeout(() => {
      this.fired = true;
      this.mousehold.emit(event);
    }, this.duration);
  }

  @HostListener('mouseup')
  mouseup() { clearTimeout(this.timeout); }

}

在视图中,我可以像这样访问此fired变量:

<span custMousehold #custMousehold="custMousehold" (click)="!custMousehold.fired ? ...

More info