4.3 Sensors -- onLongPress
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><OnLongPressas="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><buttonv-on-long-press.prevent="onLongPressCallbackDirective"class="ml-2 button small">Press long</button><buttonv-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> | undefinedfunction clear() {if (timeout) {clearTimeout(timeout)timeout = undefined}}function onDown(ev: PointerEvent) {if (options?.modifiers?.self && ev.target !== elementRef.value)returnclear()// 阻止默认事件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)
}