4.3 Sensors – onLongPress
https://vueuse.org/core/onLongPress/
作用
监控元素的长按事件。
方法提供了一些修饰符,可以在options
中指定:
stop、once、prevent、capture、self
官方示例
<script setup lang="ts">
import { ref } from 'vue'
import { onLongPress } from '@vueuse/core'
const htmlRefHook = ref<HTMLElement>()
const longPressedHook = ref(false)
function onLongPressCallbackHook(e: PointerEvent) {
longPressedHook.value = true
}
function resetHook() {
longPressedHook.value = false
}
// 这个函数是主要的
onLongPress(
htmlRefHook,
onLongPressCallbackHook,
{
modifiers: {
prevent: true
}
}
)
</script>
<template>
<p>Long Pressed: {{ longPressedHook }}</p>
<button ref="htmlRefHook" class="ml-2 button small">
Press long
</button>
<button class="ml-2 button small" @click="resetHook">
Reset
</button>
</template>
- 无渲染组件代码如下:通过
@trigger
触发回调
<script setup lang="ts">
import { ref } from 'vue'
import { OnLongPress } from '@vueuse/components'
const longPressedComponent = ref(false)
function onLongPressCallbackComponent(e: PointerEvent) {
longPressedComponent.value = true
}
function resetComponent() {
longPressedComponent.value = false
}
</script>
<template>
<p>Long Pressed: {{ longPressedComponent }}</p>
<OnLongPress
as="button"
class="ml-2 button small"
@trigger="onLongPressCallbackComponent"
>
Press long
</OnLongPress>
<button class="ml-2 button small" @click="resetComponent">
Reset
</button>
</template>
- 指令用法:
v-on-long-press
可以接收一个函数或者一个数组
<script setup lang="ts">
import { ref } from 'vue'
import { vOnLongPress } from '@vueuse/components'
const longPressedDirective = ref(false)
function onLongPressCallbackDirective(e: PointerEvent) {
longPressedDirective.value = true
}
function resetDirective() {
longPressedDirective.value = false
}
</script>
<template>
<p>Long Pressed: {{ longPressedDirective }}</p>
<button
v-on-long-press.prevent="onLongPressCallbackDirective"
class="ml-2 button small"
>
Press long
</button>
<button
v-on-long-press="[onLongPressCallbackDirective, { delay: 1000, modifiers: { stop: true } }]"
class="ml-2 button small"
>
Press long (with options)
</button>
<button class="ml-2 button small" @click="resetDirective">
Reset
</button>
</template>
源码分析
主要思路:
- 对目标元素进行监听,监听
pointerdown、pointerup、pointerleave
三个事件,按下时设置定时器 - 当按下和抬起(或者离开)的间隔,大于给定的时间(比如1.5s),则触发回调函数;
- 如果在1.5s以内抬起,则清除定时器。
- 剩下的都是一些参数,见代码注释。
⚠️:h5
可能有兼容性问题,如果这几个事件不管用,改成touch
即可。
export function onLongPress(
target: MaybeElementRef,
handler: (evt: PointerEvent) => void,
options?: OnLongPressOptions,
) {
const elementRef = computed(() => unrefElement(target))
let timeout: ReturnType<typeof setTimeout> | undefined
function clear() {
if (timeout) {
clearTimeout(timeout)
timeout = undefined
}
}
function onDown(ev: PointerEvent) {
if (options?.modifiers?.self && ev.target !== elementRef.value)
return
clear()
// 阻止默认事件
if (options?.modifiers?.prevent)
ev.preventDefault()
// 停止事件冒泡
if (options?.modifiers?.stop)
ev.stopPropagation()
timeout = setTimeout(
() => handler(ev), // 超过delay时间后,触发回调
options?.delay ?? DEFAULT_DELAY,
)
}
const listenerOptions: AddEventListenerOptions = {
// 捕获阶段执行
capture: options?.modifiers?.capture,
// 只监听一次
once: options?.modifiers?.once,
}
useEventListener(elementRef, 'pointerdown', onDown, listenerOptions)
useEventListener(elementRef, 'pointerup', clear, listenerOptions)
useEventListener(elementRef, 'pointerleave', clear, listenerOptions)
}