如何使用 Vue / JavaScript 在移动设备上触发长按(点击并按住)

Zet*_*eth 7 javascript vue.js

这仅适用于移动设备。它在桌面上按预期工作,因此我将省略所有这些样式和功能。

我有一个像这样的 Vue 组件:

模板

<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>
Run Code Online (Sandbox Code Playgroud)

所有的 div、按钮、锚点和视频都堆叠在一起,使用display: blockposition: absolute; width: 100%; etc. etc. etc.

方法

  playVideo(){
    console.log( 'Im playing!!' );
    if( this.player ){
      if( this.player.paused ){
        this.player.play()
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果我点击它,它就会按预期工作:

  • 第一次单击时,将播放视频。
  • 第二次单击时,将单击该链接。

但如果我单击并按住,则 或@click都不会@mousedown被触发。这都在:

  • 我的三星 Android 设备上的 Chrome
  • 在 iPhone 7 上的 Safari 浏览器上
  • 在我的 Mac 上的 iOS 模拟器中。...我已经检查过,当我单击并按住(长按)时,没有出现 console.logs。

那么两个问题:

  1. 我明白为什么没有被触发,因为它是和@click的组合。但为什么当我长按时没有触发?@mousedown@mouseup@mousedown
  2. 如何使用 Vue(或 JavaScript)在移动设备上定位长按?

Dan*_*hts 8

编辑:2022 年 12 月

PointerEvent是现在推荐的方式,因为它涵盖了所有设备:

<button
  v-if="!videoIsPlaying"
  @pointerdown="playVideo()"
></button>
Run Code Online (Sandbox Code Playgroud)

长按阅读:

<template>
  <button
    @pointerdown="isHolding = true"
    @pointerup="isHolding = false"
  ></button>
</template>

<script setup>
import { ref } from 'vue';

const isHolding = ref(false);
</script>
Run Code Online (Sandbox Code Playgroud)

原来的:

您需要使用TouchEvent APIPointerEvent API

两者的浏览器兼容性都很好:

它们每个都有与 MouseEvent API 相似的事件,即touchstart= mousedown

我个人发现 TouchEvents 比 PointerEvents 更好,但是,您可能需要进行一些测试才能确定哪种最适合您的情况。


因此,正如您对 Vue 所猜测的那样,您可以使用@touchstart

<button
    v-if="!videoIsPlaying"
    @click="playVideo()"
    @mousedown="playVideo()"
    @touchstart="playVideo()"
/>
Run Code Online (Sandbox Code Playgroud)

如果您想将其确定为长按,则必须在 上存储一个值touchstart并在 上更改它touchend

<button
    @touchstart="touching = true"
    @touchend="touching = false"
/>
...
data() {
    return {
        touching: false
    }
}
Run Code Online (Sandbox Code Playgroud)