This is only on Mobile devices. It works as intended on desktop, so I'll omit all those styles and functionality.
I have a Vue-component like this:
Template
<div class="container">
<div class="invisible-overlay-styles">
<button
v-if="! videoIsPlaying"
@click="playVideo()"
@mousedown="playVideo()"
>
</button>
<a
v-if="videoIsPlaying"
>
</a>
</div> <!-- invisible-overlay-styles -->
<video ... />
</div>
All the divs, buttons, anchors and videos are stacked on top of one-another, using display: block
and position: absolute; width: 100%; etc. etc. etc.
Method
playVideo(){
console.log( 'Im playing!!' );
if( this.player ){
if( this.player.paused ){
this.player.play()
}
}
}
If i click it, it works as it should:
But if I click-and-hold, then neither @click
nor @mousedown
is triggered. This is both in:
So two questions:
@click
isn't triggered, since that's a combination of @mousedown
and @mouseup
. But why doesn't @mousedown
get triggered, when I long-press?EDIT: Dec 2022
PointerEvent
is the recommended way now as it covers all devices:
<button
v-if="!videoIsPlaying"
@pointerdown="playVideo()"
></button>
To read a long-press:
<template>
<button
@pointerdown="isHolding = true"
@pointerup="isHolding = false"
></button>
</template>
<script setup>
import { ref } from 'vue';
const isHolding = ref(false);
</script>
ORIGINAL:
You'll need to use either the TouchEvent API or the PointerEvent API.
The browser compatibility for both is good:
They each have similar events to the MouseEvent API, i.e. touchstart
= mousedown
.
I've personally found TouchEvents better than PointerEvents, but, you might have to do some testing to see which is best in your case.
So, as you can guess with Vue, you can use @touchstart
:
<button
v-if="!videoIsPlaying"
@click="playVideo()"
@mousedown="playVideo()"
@touchstart="playVideo()"
/>
If you want to determine it as a long-press, you'll have to store a value on touchstart
and change it on touchend
:
<button
@touchstart="touching = true"
@touchend="touching = false"
/>
...
data() {
return {
touching: false
}
}