I want the user to be able to touch and hold an element to drag it around the page. During the drag, I want to prevent scrolling. However, I want scrolling to remain as normal if the user does not hold their finger long enough for dragging to start.
Here’s a visual way to explain what I want:
- ✅ Touch and hold for 1 second to drag without scrolling
- ✅ Touch without holding for 1 second to scroll as normal
- ✅ Touch outside the draggable to scroll as normal
However, this is behavior I do NOT want:
- ❌ Scrolling is not blocked after holding for 1 second
- ❌ Dragging starting from the draggable (without holding) blocks scrolling
Here’s the base source code for these demos: https://jsfiddle.net/yLfj2s9b/1/
Note that you will likely need to enable Device Mode in your browser’s developer tools for the demo to function: https://developer.chrome.com/docs/devtools/device-mode
However, you’ll notice that the current code allows scrolling even after holding down on the draggable for 1 second (#4 above).
I tried mitigating this by calling event.preventDefault()
in the touchstart
event handler, but that prevents scrolling before the 1 second hold (#5 above).
As another attempt, I tried storing the touchstart
event so that event.preventDefault()
can be called after the 1 second hold, but that doesn’t seem to work. Please correct me I’m wrong, but I assume event.preventDefault()
can only be called immediately after the event is fired to successfully block scrolling.
As a final attempt, I tried temporarily disabling scrolling on the page on touchstart
and reenabling it if the user fails to hold for 1 second. While this works ok for normal scrolling, it doesn’t prevent other mobile browser scrolling features like pull down to refresh, which I would also like to block in the same fashion as scrolling. So something more similar to what event.preventDefault()
does on the touchstart
event would be ideal.
Thank you very much.