2
votes

Angulaire 10 - Ne pas déclencher la fonction (clic) lors du glissement

J'ai un div avec une carte openlayers comme celle-ci:

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

J'utilise le glissement avec ma souris pour naviguer sur la carte, et chaque fois que je fais cela, getInfo code> déclencheurs de fonction. Je veux juste qu'il se déclenche lorsque je clique une fois sur la carte, pas lorsque je navigue.

Est-ce possible? Merci!


1 commentaires

Essayer de définir un écouteur OpenLayers sur l'objet de la carte, par exemple this.map.on ('singleclick', getinfo); au lieu d'utiliser le div.


4 Réponses :


0
votes

https://developer.mozilla.org/en -US / docs / Web / API / Element / click_event

Le clic se déclenche après les événements mousedown et mouseup, dans cet ordre.

Vous devrez probablement créer des gestionnaires mousedown et mouseup qui définissent une sorte d'intervalle de temps.

mousedown lancera un chronomètre ... c'est-à-dire 200 ms, et si un événement mouseup est déclenché dans cet intervalle, vous pouvez le traiter comme un clic et appeler getInfo avec l'événement passé à mouseup

si l'événement mouseup est déclenché en dehors de cet intervalle, supposez qu'il s'agit d'une action de souris glisser-déposer et ignorez-le .

@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

Vérifiez la sortie de la console sur cette démo que j'ai faite, vous verrez le comportement que vous voulez.


0 commentaires

0
votes

Vous pouvez utiliser une combinaison de liaisons d'événements click et mousedown pour gérer cette situation. Cela empêche l'événement de clic d'être déclenché si vous faites glisser votre carte.

click: boolean = false;

check() {
  window.setTimeout(this.startCheck(), 1000);
}

startCheck() {
  this.click = true;
}

getInfo(event) {
  if (this.click) {
    // handle the real click event
  }
}

Sur votre code .ts,

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


0 commentaires

10
votes

J'ai eu le même problème de détection de glisser-cliquer mais je ne voulais pas utiliser d'événements chronométrés. Si le clic est trop lent, il considère le glissement s'il le fait glisser trop rapidement, il considère le clic.

Au lieu de cela, j'ai utilisé le positionnement de la souris. Si la position x, y change entre le bas de la souris et le clic (qui est déclenché en haut de la souris), il fait glisser, sinon c'est un clic.

Pseudo-code:

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
  }
}

Fichier .ts:

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


1 commentaires

J'ai ajouté de la place pour certains déplacements de la souris en trouvant la distance. Math.abs (this.mousePosition.x - $ event.screenX) <= 5



1
votes

Ne le faites pas!

D'autres réponses donnent une réponse directe sur la manière de gérer le clic sans gérer le glisser-déposer. Ils sont bons. Mais ce qui doit être pris en compte, c'est l'expérience utilisateur. Lorsque vous faites la différence entre le clic et le glisser-déposer, vous devenez dépendant de la fluidité du fonctionnement d'un appareil utilisateur et de la façon dont l'utilisateur utilise la souris.

Par exemple: s'il y a un décalage sur un ordinateur, un ordinateur portable ou un smartphone, la solution de retard provoquera le déclenchement d'un clic au lieu d'un glissement. Dans d'autres situations, le clic ne sera pas déclenché, mais un glissement avec un conflit d'états désagréable que l'utilisateur ne pourra pas échapper.

De plus, les gens ont tendance à faire de petits mouvements avec la souris lorsqu'ils cliquent. L'interface déclenchera la traînée sur ces situations. Ou, parfois, les gens veulent faire glisser mais cliquent et accèdent à une autre page. Ils devront rentrer. C'est très ennuyeux.

Pour résumer, c'est une très mauvaise expérience utilisateur de gérer le clic et le glisser-déposer sur le même élément en même temps. Parfois, il n'est pas possible de l'éviter.

Mais chaque fois que vous le pouvez, vous devez éviter de cliquer et de faire glisser sur la même partie de l'interface utilisateur en utilisant diverses solutions de contournement.

Il existe trois vraies solutions à ce problème:

1) Utilisez une vue séparée pour réorganiser les éléments (un peu ennuyeux car il duplique la liste):

 entrez la description de l'image ici

2) Utilisez un gestionnaire de glissement (les gestionnaires de glissement peuvent être petits, donc l'utilisateur peut toujours cliquer à l'extérieur et naviguer ailleurs même s'il ne le souhaite pas):

 entrez la description de l'image ici

3) Utilisez un commutateur pour activer le glissement (meilleure solution). Veuillez noter que sur la maquette suivante, les gestionnaires de glissement doivent être masqués car la case est désactivée. Lorsque vous utilisez cette approche, toute la ligne peut être déplacée, ce qui facilite le glisser-déposer. Le gestionnaire de glisser peut toujours être affiché pour indiquer quel changement dans l'interface utilisateur (hé utilisateur, maintenant vous pouvez glisser-déposer!)

 entrez la description de l'image ici


0 commentaires