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
},
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
},
Share
Improve this question
asked Jan 8, 2018 at 14:27
GiacomoGiacomo
1,0964 gold badges16 silver badges26 bronze badges
4
|
2 Answers
Reset to default 39You 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
},
if
that checks whether the variable is set. – Roy J Commented Jan 8, 2018 at 15:10