没有“ 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
始终会触发。
答案 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 ? ...