Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item in array with a (click) event fired on "mouse up" #143

Open
arcio opened this issue Feb 7, 2018 · 2 comments
Open

Item in array with a (click) event fired on "mouse up" #143

arcio opened this issue Feb 7, 2018 · 2 comments

Comments

@arcio
Copy link

arcio commented Feb 7, 2018

If I drag the carousel left <> right, when I mouse up, it fires a (click) event to the object in the array.

<ngx-slick class="carousel" #slickModal="slick-modal" [config]="slideConfig" width="100%">
  <div *ngFor="let story of stories | async; let i = index" ngxSlickItem class='slide' width="100%">
    <feature-story class="story-type-a" [title]="story?.headline" [storyID]="story?.$key" [handle]="story?.handle" [avatar]="story?.avatar"
      [date]="story?.timestamp" [storyImage]="story?.image" [bgColor]="story?.bgColor" [category]="story?.category"></feature-story>
  </div>
</ngx-slick>

feature-story itself has a click handler (click)="GoToStory(storyID)"

Is there a simple way to disable this? It doesn't appear to be happening on mobile, only with the mouse/trackpad.

@joscmw95
Copy link

joscmw95 commented Apr 12, 2018

This is due to the way navigation is handled in Angular.
Despite a drag, Angular still thinks that it is a mouse click hence triggering the event.

One of the ways to work around this situation is to use a timer on the mousedown event and assume that any (mousedown -> mouseup) that happens in a specified interval is a click:

// fires on mousedown, "(mousedown)=trackMouse()"
trackMouse() {
  this.mouseDown = true;
  window.setTimeout(() => {
    this.mouseDown = false;
  }, 100);
}

// fires on click, "(click)=navigateIfClick(item)"
navigateIfClick(item) {
  if (this.mouseDown) {
    this.router.navigate(['/item/', item.id]);
  }
}

A better solution could be tracking the position of the mousedown and mouseup event and assume it is a click if both events' positions are close.

trackMouseDown(event: MouseEvent) {
  this.x1 = event.x;
  this.y1 = event.y;
}

trackMouseUp(event: MouseEvent, item: Item) {
  let a = this.x1 - event.x;
  let b = this.y1 - event.y;
  let c = Math.sqrt(a * a + b * b);

  if (c < 10) {
    switch (event.which) {
      case 1:
        // left click
        this.router.navigate(['/items/', item.id]);
        break;
      case 2:
        // middle button
        window.open(window.location.hostname + `/items/${item.id}`, '_blank');
        break;
      case 3:
        // right click
        break;
      default:
        this.router.navigate(['/items/', item.id]);
        break;
    }
  }
}

@arcio
Copy link
Author

arcio commented Apr 23, 2018

Thanks! This worked like a charm, with one exception. I had to use an event listener as the function isn't always passed through from the component.
document.getElementById("ID_NAME").addEventListener("mousedown", function(e) {self.FUNCTION_NAME(e);});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants