Javascript 角度10-拖动时不触发(单击)功能

Javascript 角度10-拖动时不触发(单击)功能,javascript,angular,function,triggers,click,Javascript,Angular,Function,Triggers,Click,我有一个带有openlayers贴图的div,如下所示: <div id="map" (click)="getInfo($event)" class="map"></div> 我使用鼠标拖动在地图上导航,每次这样做时,getInfo函数都会触发。我只希望它在我单击地图时触发,而不是在我导航时触发 可能吗?谢谢 在mousedown和mouseup事件之后,按顺序单击fires 您可能需要创建mousedown和mouseup处理程序来设置某种时间间隔 moused

我有一个带有openlayers贴图的div,如下所示:

<div id="map" (click)="getInfo($event)" class="map"></div>

我使用鼠标拖动在地图上导航,每次这样做时,
getInfo
函数都会触发。我只希望它在我单击地图时触发,而不是在我导航时触发

可能吗?谢谢

在mousedown和mouseup事件之后,按顺序单击fires

您可能需要创建mousedown和mouseup处理程序来设置某种时间间隔

mousedown将启动一些计时器。。。如果在该时间间隔内触发了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')
}


检查我制作的这个演示上的控制台输出,你会看到你想要的行为。

你可以结合使用
单击
鼠标向下
事件绑定来处理这种情况。这将防止在拖动地图时触发单击事件

<div id="map" (mousedown)="check($event)" (click)="getInfo($event)" class="map"></div>

我在检测拖动和单击时遇到同样的问题,但不想使用定时事件。如果单击过慢,则考虑拖动;如果拖动过快,则考虑单击

相反,我使用鼠标定位。如果x、y位置在鼠标向下和单击之间发生变化(鼠标向上时触发),则表示拖动,否则表示单击

伪代码:

<div (mousedown)="onMouseDown($event)" (click)="onClick($event)"></div>

不要这样做

其他答案给出了如何在不处理拖放的情况下完成处理单击的直接答案。它们很好。但需要考虑的是用户体验。当您区分单击和拖放时,您将取决于用户设备工作的顺畅程度以及用户操作鼠标的方式

例如:如果电脑、笔记本电脑或智能手机出现延迟,延迟解决方案将导致触发单击而不是拖动。在其他情况下,单击将不会被触发,但用户将无法逃脱带有严重状态冲突的拖动

此外,人们在点击时往往会用鼠标做一些小动作。在这些情况下,界面将触发拖动。或者,有时人们想拖动,但会单击并导航到另一个页面。他们需要回去。这很烦人

总而言之,在同一时间处理同一元素上的点击和拖放是一种非常糟糕的用户体验。有时是无法避免的

但是,每次都可以,您应该避免使用各种变通方法在UI的同一部分上单击和拖动

这个问题有三种真正的解决方案:

1)使用单独的视图对项目重新排序(有点烦人,因为它复制了列表):

2)使用拖动处理程序(拖动处理程序可以很小,所以用户仍然可以在其外部单击并导航到其他位置,即使他不想):

3)使用开关启用拖动(最佳解决方案)。请注意,由于复选框处于禁用状态,因此在以下实体模型上,应该隐藏拖动处理程序。使用这种方法时,整行可以拖动,从而更容易拖放。拖动处理程序仍然可以显示,以指示UI中的更改(嘿,用户,现在您可以拖放!)


尝试在地图对象上设置OpenLayers侦听器,例如,
this.map.on('singleclick',getinfo)而不是使用div。我通过查找距离为鼠标移动增加了空间<代码>Math.abs(this.mousePosition.x-$event.screenX)
<div (mousedown)="onMouseDown($event)" (click)="onClick($event)"></div>
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
  }
}