我有一个带有openlayers地图的div,如下所示:
<div id="map" (click)="getInfo($event)" class="map"></div>
我使用鼠标拖动来浏览地图,每次执行 getInfo 函数都会触发。我只希望它在单击地图时触发,而不是在导航时触发。
有可能吗?谢谢!
答案 0 :(得分:1)
不要这样做!
其他答案则直接回答了如何完成单击操作而不需要拖放。他们很好。但是需要考虑的是用户体验。当您区分单击和拖放时,您将取决于用户设备的运行状况以及用户如何操作鼠标。
例如:如果计算机,笔记本电脑或智能手机上存在延迟,则延迟解决方案将导致触发点击而不是拖动。在其他情况下,将不会触发点击,而是会产生拖曳状态的拖拽,使用户无法逃脱。
此外,人们在单击时倾向于用鼠标进行小动作。该界面将在这些情况下触发拖动。或者,有时人们想拖动但会单击并导航到另一页面。他们将需要回去。真烦人。
总结起来-同时处理同一元素上的单击和拖放操作是非常糟糕的用户体验。有时无法避免。
但是每次您都可以避免使用各种变通方法在用户界面的同一部分上单击和拖动。
此问题有三种真正的解决方案:
1)使用单独的视图对项目进行重新排序(由于它与列表重复而有些烦人):
2)使用拖动处理程序(拖动处理程序可能很小,因此即使用户不愿意,仍然可以在其外部单击并导航到其他地方):
3)使用开关启用拖动(最佳解决方案)。请注意,由于复选框处于关闭状态,因此在下面的模型中应隐藏拖动处理程序。使用这种方法时,整个行都是可拖动的,因此拖放起来更容易。仍然可以显示拖动处理程序以指示UI中的更改(嘿,用户,现在您可以拖放!)
答案 1 :(得分:0)
https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
click在mousedown和mouseup事件发生后按此顺序触发。
您可能必须创建设置某些时间间隔的mousedown和mouseup处理程序。
mousedown将启动一个计时器...即200毫秒,如果在该间隔内触发mouseup事件,则可以将其视为单击并通过将事件传递给mouseup来调用getInfo
如果在该间隔之外触发了mouseup事件,请假定这是拖放操作,并忽略它。
@ViewChild('map') mapElem: ElementRef;
ngAfterViewInit() {
const mousedown$ = fromEvent(this.mapElem.nativeElement, 'mousedown');
const mouseup$ = fromEvent(this.mapElem.nativeElement, 'mouseup');
mousedown$.subscribe(e => {
const clickTimer$ = timer(200);
mouseup$.pipe(takeUntil(clickTimer$)).subscribe(e => this.getInfo(e));
});
}
getInfo(e) {
console.log('click')
}
https://stackblitz.com/edit/angular-sobuqt
在我制作的此演示中检查控制台输出,您将看到所需的行为。
答案 2 :(得分:0)
您可以结合使用click
和mousedown
事件绑定来处理这种情况。这样可以防止在拖动地图时触发click事件。
<div id="map" (mousedown)="check($event)" (click)="getInfo($event)" class="map"></div>
在您的.ts代码上,
click: boolean = false;
check() {
window.setTimeout(this.startCheck(), 1000);
}
startCheck() {
this.click = true;
}
getInfo(event) {
if (this.click) {
// handle the real click event
}
}
答案 3 :(得分:0)
我在检测拖动与单击时遇到了相同的问题,但不想使用定时事件。如果单击得太慢,则考虑拖动。如果拖动得太快,则认为单击。
相反,我使用鼠标定位。如果x,y位置在鼠标下移与单击之间改变(在鼠标上移时触发),则为拖动,否则为拖动。
伪代码:
<div (mousedown)="onMouseDown($event)" (click)="onClick($event)"></div>
.ts文件:
mousePosition = {
x: 0,
y: 0
};
mouseDown($event) {
this.mousePosition.x = $event.screenX;
this.mousePosition.y = $event.screenY;
}
onClick(selectedWidget, $event) {
if (this.mousePosition.x === $event.screenX && this.mousePosition.y === $event.screenY) {
// Execute Click
}
}