将元素拖到 div 中,但元素在拖动时会闪烁

Dragging an element inside a div but the element flashes when dragged

我正在尝试将一个元素拖到另一个 div 内部,但它在被拖来拖去时一直在闪烁。我用这个沙箱重现了这个问题 https://codesandbox.io/s/focused-cache-l3yos

<template>
  <div id="app">
    <div id="board" @mousemove="dragOver">
      <div
        class="draggableItem"
        @mousedown="dragStart"
        @mouseup="dragStop"
        :style="{top: this.top + 'px', left: this.left + 'px'}"
      >This should be draggable</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data: function() {
    return {
      isDragging: false,
      top: 50,
      left: 50
    };
  },
  methods: {
    dragOver: function(e) {
      if (this.isDragging) {
        this.left = e.offsetX;
        this.top = e.offsetY;
      }
    },
    dragStart: function(e) {
      this.isDragging = true;
    },
    dragStop: function(e) {
      this.isDragging = false;
    }
  }
};
</script>

您可以将位置计算为与起始位置的偏移量,然后根据移动更新它。这将允许通过任何部分绘制。您可以(并且应该恕我直言)动态附加和删除事件处理程序。

这可能是这样的:

<template>
  <div id="app">
    <div id="board">
      <div
        class="draggableItem"
        @mousedown="dragStart"
        :style="{top: this.top + 'px', left: this.left + 'px'}"
      >This should be draggable</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data: function() {
    return {
      isDragging: false,
      top: 50,
      left: 50,
      startTop: 0,
      startLeft: 0
    };
  },
  methods: {
    dragOver: function(e) {
      if (this.isDragging) {
        this.top = e.clientY - this.startTop;
        this.left = e.clientX - this.startLeft;
      }
    },
    dragStart: function(e) {
      window.addEventListener('mousemove', this.dragOver)
      window.addEventListener('mouseup', this.dragStop)
      this.isDragging = true;
      this.startTop = e.clientY - this.top;
      this.startLeft = e.clientX - this.left;
    },
    dragStop: function(e) {
      window.removeEventListener('mousemove', this.dragOver)
      window.removeEventListener('mouseup', this.dragStop)
      this.isDragging = false;
    }
  }
};
</script>