In my case in desktop mode user can hover over the element to reveal the menu. User can also click the element that makes a request to the server.
In touchscreen mode, I would like the click to be revealing the menu instead of making a request.
It seems like impossible task to achieve unless I start going outside of vue and changing css directly from DOM level.
<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 >
<span v-show="!isEditing" @click="sendToServer" @touchstart.prevent> {{ text }}</span>
<input v-show="isEditing" v-model="text">
<span @click="sendToServer" >➡️</span>
<span @click="isEditing = !isEditing" >✏️</span>
</div>
</template>
<style>
.icon {
opacity: 0;
}
.wrapper:hover .icon {
opacity: 1;
}
.wrapper > span {
cursor: pointer;
}
</style>
CodePudding user response:
"It seems like impossible task to achieve unless I start going outside of vue and changing css directly from DOM level."
I would say it is impossible to achieve with CSS-only, but Vue (IMHO) seems cable and well suited to handle that.
Instead of using css :hover
you will need to manage the visibility using state (isSelected
in example)
then use @touchstart
to toggle visibility - this will only be available to touch devices and mouse events @mouseover
to show and @mouseout
to hide.
there may be some more finessing to handle some edge cases, but this is how I'd implement it. For example, you may need a global touch event listener to hide when user clicks outside of the text.
<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 >
<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" >➡️</span>
<span v-show=isSelected @click="isEditing = !isEditing" >✏️</span>
</div>
</template>
<style>
.wrapper > span {
cursor: pointer;
}
</style>