Any ionic master with an example on how to create the long press gesture? Latest info I found is 3 years old with references to articles that don’t exist no more.
made a directive if anyone needs
// v-long-press.js
export default {
beforeMount(el, binding) {
// Define start and cancel functions as properties on the element
el._pressTimer = null
el._start = (e) => {
if (el._pressTimer === null) {
el._pressTimer = setTimeout(() => {
binding.value(e)
clearTimeout(el._pressTimer)
el._pressTimer = null
}, 600)
}
}
el._cancel = () => {
if (el._pressTimer !== null) {
clearTimeout(el._pressTimer)
el._pressTimer = null
el.isOpen = false
}
}
// Add event listeners for touch events
el.addEventListener("touchstart", el._start)
el.addEventListener("touchend", el._cancel)
el.addEventListener("touchcancel", el._cancel)
},
unmounted(el) {
// Remove event listeners using the functions stored on the element
el.removeEventListener("touchstart", el._start)
el.removeEventListener("touchend", el._cancel)
el.removeEventListener("touchcancel", el._cancel)
// Clean up references
delete el._start
delete el._cancel
delete el._pressTimer
},
}
in component script
import vLongPress from "./v-long-press"
...
directives: {
longPress: vLongPress,
},
in component template
<ion-button v-long-press="handleClickActionSheet" color="clear">
{{ currentMealType.name }}
</ion-button>
NOTE: works only on phone, in webview (chrome console in my case) the touch events intervene with native scrolling, not sure how, but deployed on the phone it works as expected
also the first one I shared will get triggered on swipe if swipe lasts over 600ms … so if you have ion-sliding-item
and you want to use the v-long-press
on some element there … use this directive
// v-long-press.js
export default {
beforeMount(el, binding) {
// Initialize variables on the element to track state
el._pressTimer = null
el._startX = 0
el._startY = 0
el._moved = false
// Start function to initiate long press detection
el._start = (e) => {
el._moved = false // Reset move flag
if (e.type === "touchstart") {
// Track initial touch position
el._startX = e.touches[0].clientX
el._startY = e.touches[0].clientY
}
// Set a timer for the long press
if (el._pressTimer === null) {
el._pressTimer = setTimeout(() => {
if (!el._moved && typeof binding.value === "function") {
binding.value(e)
}
clearTimeout(el._pressTimer)
el._pressTimer = null
}, 600)
}
}
// Move function to detect swipe or drag
el._move = (e) => {
const currentX = e.touches[0].clientX
const currentY = e.touches[0].clientY
// Check if the touch has moved significantly (swipe/scroll)
if (Math.abs(currentX - el._startX) > 10 || Math.abs(currentY - el._startY) > 10) {
el._moved = true // Mark as moved
el._cancel() // Cancel the long press
}
}
// Cancel function to clear timer and reset state
el._cancel = () => {
if (el._pressTimer !== null) {
clearTimeout(el._pressTimer)
el._pressTimer = null
}
}
// Add event listeners
el.addEventListener("touchstart", el._start)
el.addEventListener("touchmove", el._move)
el.addEventListener("touchend", el._cancel)
el.addEventListener("touchcancel", el._cancel)
},
unmounted(el) {
// Clean up event listeners on unmount
el.removeEventListener("touchstart", el._start)
el.removeEventListener("touchmove", el._move)
el.removeEventListener("touchend", el._cancel)
el.removeEventListener("touchcancel", el._cancel)
// Clean up properties
delete el._start
delete el._move
delete el._cancel
delete el._pressTimer
delete el._startX
delete el._startY
delete el._moved
},
}
I just used onLongPress | VueUse
I actually knew about it I swear but I would install the package solely just for this directive which felt excessive. If I bump into a scenario where i need some other vueuse stuff I will get the package and just replace this, for for now if i need just the long press I’ll choose my 2KB version
I had the same thought, but with tree shaking the addition should be tiny. I went with it so as to not reinvent the wheel.
ou I didn’t know that, do I have to set up something special for tree shaking to occur or does it happen on build by itself? Because of course if I can just use something well maintained that’s always better, my decision was only size based
Tree shaking should just work out of the box if you are using standard Vue bundling (Vite currently). All of Ionic’s components are also “shook”.
Wouldn’t it make sense to call the haptics api to give feedback to the user?
oh of course! completely forgot about this, that’s awesome, thank you!