Re: [pointerevents] Pointer capture should prevent HTML drag+drop (DnD)

I definitely hear the arguments for simplicity and consistency with existing APIs.  There's a counterargument for explicitness and obviousness: I don't think I've ever seen HTML5 drag-and-drop used in a touch UI.  Gestural interaction is the natural modality of touch UI.  Favoring drag-and-drop at the expense of pointer events makes the common case harder to get right in order to support a feature (touch-based drag-and-drop) that isn't being used in practice.

Since pointer events are a new feature, I think there's still room to define how they interoperate with the `draggable` attribute.  If `draggable` was popular, I'd be more amenable to allowing drag to trump pointer capture.  However, because I don't believe it is, **this is my proposal:**

1. **Explicitly captured pointers (e.g. by `element.setPointerCapture`) don't participate in HTML drag-and-drop:** `pointer{down,move,up}` dispatch as if dragging doesn't exist, and `dragstart` et. al. never happen.
2. **Explicitly `draggable` elements dispatch `pointercancel` & `lostpointercapture` immediately before `dragstart`.**  Calling `downEvent.preventDefault()` overrides this by preventing `dragstart` from ever happening.

This leaves the questions of what to do with touches.  

**Question: Does `dragstart` et. al. ever dispatch on a touchscreen if the `draggable` attribute hasn't also been set?**

- If not, fantastic.  That means touch pointers already behave as I've proposed (with the exception of sending `pointercancel` - a bug we need to fix).  By making explicit pointer capture also suppress `dragstart`, we've made the API more predictable and consistent.  🎉 

- However, if there is a case where a developer could expect `drag` on a touch device without explicitly using `draggable`, then we have a potential compatibility issue.  In that case, perhaps the best solution is to dispatch `pointercancel` before `dragstart` for touch interactions _unless_ `setPointerCapture` has explicitly been called.  (@NavidZ's proposal)

My proposal is a pragmatic one - I realize it might be a bit gross as a spec.  However, it does the right thing by default, while still supporting the uncommon use of `draggable` in conjunction with touch.


I think we all agree that when the platform isn't predictable and consistent, we have a problem.  Unfortunately, that's already the case.  An author who only knows about `pointer{down, move, and up}` can build a gesture recognizer now that works great on touch screens and usually for mice too.  However, if the user happens to use a mouse and begin the gesture on an image or a link, HTML drag-and-drop kicks in (even if the author has explicitly used pointer capture to declare that they want to handle the gesture).  Hopefully, the author catches this in testing, but both because content can be dynamic and because not everyone has the time and resources to test on every device, we know that in practice it can go uncaught, yielding a frustrating user experience.

After the author realizes that `dragstart` is interrupting the pointer stream, they then also have to know that `dragstart` is prevented by calling `downEvent.preventDefault()` (not the more obvious `dragstartEvent.preventDefault()`).  This is an intimidating decision, because now the author also has to know all the default behavior that might follow a down event and opt in to cancelling all of it.

**I'm concerned that the status quo requires the author to master too many separate concepts before effectively using pointer events.**

The point of Pointer Events is to enable authors to implement gestural input once and to have it work consistently across input modalities.  `dragstart` is literally interrupting that goal.  By prioritizing pointer capture over HTML `draggable`, we minimize the number of concepts a developer has to master to get gestures right and eliminate an unfortunate footgun.

GitHub Notification of comment by appsforartists
Please view or discuss this issue at using your GitHub account

Received on Monday, 26 June 2017 15:23:56 UTC