How can I prevent click on drag?
Asked Answered
E

1

6

I am trying to have an element with both a drag and click event. I have read about and tried a combination of event modifiers.

However, no matter what I try, I get a click when drag is stopped.

Note, in the MWE this is done on the component itself, but in my actual app I am using .native modifier to drag a component

How can I drag without click?

Edit Drag Click

Component Draggable:

<template>
  <div
    @pointerdown="handleDown"
    @pointerup="handleUp"
    @pointercancel="handleUp"
    @click="click = !click;"
    :style="style"
    ref="draggableRoot"
    class="draggable"
  >
    drag me!<br />
    am dragged? {{ drag }}<br />
    am clicked? {{ click }}<br />
  </div>
</template>
<script>
export default {
  computed: {
    style() {
      return {
        left: `${this.x}px`,
        top: `${this.y}px`
      };
    }
  },
  data() {
    return {
      x: 100,
      y: 100,
      left: 0,
      top: 0,
      drag: false,
      click: false
    };
  },
  methods: {
    handleMove({ pageX, pageY, clientX, clientY }) {
      if (this.$refs.draggableRoot) {
        this.x = pageX + this.left;
        this.y = pageY + this.top;
        this.drag = true;
      }
    },
    handleDown(event) {
      const { pageX, pageY } = event;
      const { left, top } = this.$refs.draggableRoot.getBoundingClientRect();
      this.left = left - pageX;
      this.top = top - pageY;
      document.addEventListener("pointermove", this.handleMove);
    },
    handleUp() {
      document.removeEventListener("pointermove", this.handleMove);
      this.drag = false;
    }
  }
};
</script>
<style scoped>
.draggable {
  position: fixed;
  border: solid coral 1px;
  height: 100px;
}
</style>
Ellie answered 10/12, 2018 at 9:52 Comment(0)
E
7

Maybe that would work:

Add setTimeout inside method handleUp:

handleUp() { 
  document.removeEventListener("pointermove", this.handleMove);
  setTimeout(() => this.drag = false) //this would move this assigment at the end of event queue
}

Also add new method handleClick and assing it to event @click:

handleClick() {
  if(!this.drag) { //change click only if not draged
    this.click = !this.click
  }
}

Seems to work!

Eustatius answered 10/12, 2018 at 21:43 Comment(3)
no idea? maybe they were using Safair? This works in Moz and Chrome. Any idea how to make it work in Safair?Ellie
I've got no way to test it, but maybe try adding very small delay on setTimeout, like 50ms. Try setTimeout(() => this.drag = false, 50)Clearsighted
the timeout seems to be ok in Safari it is the drag all together :p. Ill look into it. In the mean time Ill wait to accept an answer to see if there is a vue native way to solve this :) Thanks for the help thoEllie

© 2022 - 2024 — McMap. All rights reserved.