[英]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.