Skip to content

When using pointers.touch = true, conditionally calling preventDefault has flaky behavior in iOS #685

@stephen

Description

@stephen

Describe the bug

I want to conditionally call event.preventDefault to cancel scrolling (use case: implementing pull to refresh where my custom behavior only happens at the top of scrollTop). On iOS, I noticed that sometimes (half?), the event passed would have event.cancelable === false and would still scroll while my drag ran.

I noticed that useDrag() only attaches touchstart event at rest. I found this stackoverflow answer that matches my symptoms.

The following patch corrects the issue for me, confirming the diagnosis:

diff --git a/node_modules/@use-gesture/core/dist/actions-76b8683e.esm.js b/node_modules/@use-gesture/core/dist/actions-76b8683e.esm.js
index 9322a47..e5492e2 100644
--- a/node_modules/@use-gesture/core/dist/actions-76b8683e.esm.js
+++ b/node_modules/@use-gesture/core/dist/actions-76b8683e.esm.js
@@ -826,10 +826,12 @@ class DragEngine extends CoordinatesEngine {
   bind(bindFunction) {
     const device = this.config.device;
     bindFunction(device, 'start', this.pointerDown.bind(this));
-    if (this.config.pointerCapture) {
+    if (this.config.pointerCapture || this.config.device === 'touch') {
       bindFunction(device, 'change', this.pointerMove.bind(this));
       bindFunction(device, 'end', this.pointerUp.bind(this));
       bindFunction(device, 'cancel', this.pointerUp.bind(this));
+    }
+    if (this.config.pointerCapture) {
       bindFunction('lostPointerCapture', '', this.pointerUp.bind(this));
     }
     if (this.config.keys) {

I am not recommending this patch, but this is the workaround I'm using to fix this for now.

Information:

  • Use Gesture version: ^10.2.27
  • Device: iPhone 15
  • OS: iOS 18.2
  • Browser: stock safari

Checklist:

  • I've read the documentation.
  • If this is an issue with drag, I've tried setting touch-action: none to the draggable element. I did not do this because I want to be able to conditionally choose if the browser's default drag is activated or not.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions