Vue mousemove only after mousedown

隐身守侯 提交于 2019-12-05 07:01:20

You will want to have a mousedown listener on your element that sets a variable to indicate dragging started. Put a listener on the window to catch mouseup anywhere and unset the variable.

You can put mousemove on the element if you are only interested in dragging that happens inside the element. Otherwise you can put the mousemove listener on window so you catch it everywhere.

new Vue({
  el: '#app',
  data: {
    dragging: false,
    x: 'no',
    y: 'no'
  },
  methods: {
    startDrag() {
      this.dragging = true;
      this.x = this.y = 0;
    },
    stopDrag() {
      this.dragging = false;
      this.x = this.y = 'no';
    },
    doDrag(event) {
      if (this.dragging) {
        this.x = event.clientX;
        this.y = event.clientY;
      }
    }
  },
  mounted() {
    window.addEventListener('mouseup', this.stopDrag);
  }
});
.dragstartzone {
  background-color: red;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div class="dragstartzone" @mousedown="startDrag" @mousemove="doDrag">Start dragging here</div>
  <div>X: {{x}}, Y: {{y}}</div>
</div>

I ended up using the code provided by Roy J, refactoring it a bit to fit my need. Here it is

Template:

.player__time--bar(@mousedown="startDrag($event)" @mouseup="stopDrag($event)" @mousemove="doDrag($event)")
    .slider(role="slider" aria-valuemin="0" :aria-valuenow="currentPosition" :aria-valuemax="trackTotalDuration" aria-orientation="horizontal")
        .player__time--bar-current-position(:style="{width:  (100 / (trackTotalDuration / currentPosition)) + '%'}")

Data:

data: () => ({
    currentPosition: 0,
    trackTotalDuration: 0,
    dragging: false
}),

Methods:

startDrag() {
    this.dragging = true
},
stopDrag(event) {
    this.dragging = false
    this.setNewCurrentPosition(event)
},
doDrag(event) {
    if (this.dragging) this.setNewCurrentPosition(event)
},

setNewCurrentPosition(e) {
    let tag = e.target
    // if the click is not on 'slider', grab div with class 'slider'
    if (e.target.className === 'player__time--bar') tag = e.target.firstElementChild
    else if (e.target.className === 'player__time--bar-current-position') tag = e.target.parentElement
    const pos = tag.getBoundingClientRect()
    const seekPos = (e.clientX - pos.left) / pos.width
    this.currentPosition = parseInt(this.trackTotalDuration * seekPos)
    // updates the time in the html
    this.$refs.player.currentTime = this.currentPosition
},
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!