Comment puis-je déclencher un déplacement de souris uniquement si l'élément est cliqué en premier? ... J'essaie de l'utiliser pour un scénario de lecteur audio.
.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)) + '%'}")
La méthode:
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
},
Vous voudrez avoir un écouteur mousedown
sur votre élément qui définit une variable pour indiquer que le glissement a commencé. Placez un écouteur sur la fenêtre pour intercepter mouseup
n'importe où et désélectionnez la variable.
Vous pouvez mettre mousemove
sur l'élément si vous êtes uniquement intéressé par un déplacement qui se produit à l'intérieur de l'élément. Sinon, vous pouvez mettre l'auditeur mousemove
sur window
afin de l'attraper partout.
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>
J'ai fini par utiliser le code fourni par Roy J, en le refacturant un peu pour l'adapter à mes besoins. C'est ici
Modèle:
.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)) + '%'}")
Les données:
data: () => ({
currentPosition: 0,
trackTotalDuration: 0,
dragging: false
}),
Les méthodes:
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
},