如何检测触摸屏设备上的悬停状态 - Vue 3
How to detect hover state on touchscreen device - Vue 3
在我的例子中,在桌面模式下,用户可以将鼠标悬停在元素上以显示菜单。用户还可以单击向服务器发出请求的元素。
在触摸屏模式下,我希望点击显示菜单而不是发出请求。
这似乎是不可能完成的任务,除非我开始走出 vue 并直接从 DOM 级别更改 css。
<script setup>
import { ref } from "vue";
const text = ref("whatever");
const isEditing = ref(false);
function sendToServer() {
console.log("Sending request of ", text.value, " to server.")
isEditing.value = false;
}
</script>
<template>
<div class="wrapper">
<span v-show="!isEditing" @click="sendToServer" @touchstart.prevent> {{ text }}</span>
<input v-show="isEditing" v-model="text">
<span @click="sendToServer" class="icon">➡️</span>
<span @click="isEditing = !isEditing" class="icon">✏️</span>
</div>
</template>
<style>
.icon {
opacity: 0;
}
.wrapper:hover .icon {
opacity: 1;
}
.wrapper > span {
cursor: pointer;
}
</style>
“这似乎是不可能完成的任务,除非我开始走出 vue 并直接从 DOM 级别更改 css。”
我会说用 CSS-only 是不可能实现的,但是 Vue(恕我直言)似乎很强大并且很适合处理这个问题。
而不是使用 css :hover
您将需要使用状态来管理可见性(例如 isSelected
)
然后使用 @touchstart
切换可见性 - 这将仅适用于触摸设备和鼠标事件 @mouseover
显示和 @mouseout
隐藏。
处理一些边缘情况可能需要更多技巧,但这就是我实现它的方式。例如,您可能需要一个全局触摸事件侦听器,以便在用户单击文本外部时隐藏。
<script setup>
import { ref } from "vue";
const text = ref("whatever");
const isEditing = ref(false);
const isSelected = ref(false);
function toggleIsSelected(){
isSelected.value = !isSelected.value
}
function unselect(){
isSelected.value = false;
}
function sendToServer() {
console.log("Sending request of ", text.value, " to server.")
isEditing.value = false;
}
</script>
<template>
<div class="wrapper">
<span v-show="!isEditing"
@click="sendToServer"
@touchstart=toggleIsSelected
@mouseover=toggleIsSelected
@mouseout=unselect
> {{ text }}</span>
<input v-show="isEditing" v-model="text">
<span v-show=isSelected @click="sendToServer" class="icon">➡️</span>
<span v-show=isSelected @click="isEditing = !isEditing" class="icon">✏️</span>
</div>
</template>
<style>
.wrapper > span {
cursor: pointer;
}
</style>
在我的例子中,在桌面模式下,用户可以将鼠标悬停在元素上以显示菜单。用户还可以单击向服务器发出请求的元素。
在触摸屏模式下,我希望点击显示菜单而不是发出请求。
这似乎是不可能完成的任务,除非我开始走出 vue 并直接从 DOM 级别更改 css。
<script setup>
import { ref } from "vue";
const text = ref("whatever");
const isEditing = ref(false);
function sendToServer() {
console.log("Sending request of ", text.value, " to server.")
isEditing.value = false;
}
</script>
<template>
<div class="wrapper">
<span v-show="!isEditing" @click="sendToServer" @touchstart.prevent> {{ text }}</span>
<input v-show="isEditing" v-model="text">
<span @click="sendToServer" class="icon">➡️</span>
<span @click="isEditing = !isEditing" class="icon">✏️</span>
</div>
</template>
<style>
.icon {
opacity: 0;
}
.wrapper:hover .icon {
opacity: 1;
}
.wrapper > span {
cursor: pointer;
}
</style>
“这似乎是不可能完成的任务,除非我开始走出 vue 并直接从 DOM 级别更改 css。”
我会说用 CSS-only 是不可能实现的,但是 Vue(恕我直言)似乎很强大并且很适合处理这个问题。
而不是使用 css :hover
您将需要使用状态来管理可见性(例如 isSelected
)
然后使用 @touchstart
切换可见性 - 这将仅适用于触摸设备和鼠标事件 @mouseover
显示和 @mouseout
隐藏。
处理一些边缘情况可能需要更多技巧,但这就是我实现它的方式。例如,您可能需要一个全局触摸事件侦听器,以便在用户单击文本外部时隐藏。
<script setup>
import { ref } from "vue";
const text = ref("whatever");
const isEditing = ref(false);
const isSelected = ref(false);
function toggleIsSelected(){
isSelected.value = !isSelected.value
}
function unselect(){
isSelected.value = false;
}
function sendToServer() {
console.log("Sending request of ", text.value, " to server.")
isEditing.value = false;
}
</script>
<template>
<div class="wrapper">
<span v-show="!isEditing"
@click="sendToServer"
@touchstart=toggleIsSelected
@mouseover=toggleIsSelected
@mouseout=unselect
> {{ text }}</span>
<input v-show="isEditing" v-model="text">
<span v-show=isSelected @click="sendToServer" class="icon">➡️</span>
<span v-show=isSelected @click="isEditing = !isEditing" class="icon">✏️</span>
</div>
</template>
<style>
.wrapper > span {
cursor: pointer;
}
</style>