Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
1 of 2 tasks
stephen opened this issue Dec 5, 2024 · 0 comments
Assignees

Comments

@stephen
Copy link

stephen commented Dec 5, 2024

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.
@stephen stephen changed the title When using pointers.touch = true, conditionally calling preventDefault has flaky behavior in iOS When using pointers.touch = true, conditionally calling preventDefault has flaky behavior in iOS Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants