简体   繁体   English

Vue只在mousedown之后移动

[英]Vue mousemove only after mousedown

How can I trigger a mousemove only if the element is clicked first? 如果首先单击元素,如何触发鼠标移动? I'm trying to utilize this for an audio player timeline. 我正在尝试将其用于音频播放器时间线。

.player__time--bar(@mousedown="setNewCurrentPosition($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)) + '%'}")

The method: 方法:

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

You will want to have a mousedown listener on your element that sets a variable to indicate dragging started. 您将希望在元素上设置一个mousedown侦听器,该侦听器设置一个变量以指示拖动已开始。 Put a listener on the window to catch mouseup anywhere and unset the variable. 在窗口上放置一个监听器以捕获任何地方的mouseup并取消设置该变量。

You can put mousemove on the element if you are only interested in dragging that happens inside the element. 如果您只对拖动元素内部发生的事情感兴趣,可以将mousemove放在元素上。 Otherwise you can put the mousemove listener on window so you catch it everywhere. 否则,您可以将mousemove侦听器放在window以便随处捕获它。

 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. 我最终使用了Roy J提供的代码,重构了一下以满足我的需求。 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
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM