Re: [w3c/uievents] MouseEvent.fromElement/toElement (#84)

Stumbled upon this trying to figure out how to implement dragging a file into a web page.

The problem is that the drag-and-drop API is very finicky.  There is a firehose of events that fire during a drag, a mix of `dragenter`, `dragover`, and `dragleave`s.  Even though you have to call `event.preventDefault()` inside a `dragover` to claim responsibility for a drag, the events are all dispatched from children.  The naive implementation - setting a style inside `dragover` and removing it in `dragleave` - causes flickering, where the style is present in odd numbered frames and removed in even numbered frames, because the children are being entered/left even though the drag is still hovering over the drop target.

The current best practice is to count the number of `dragenter` and `dragleave` events, using the balance to determine whether or not the drop target is being hovered over.  It's a hack to paper over an unfortunate API.

`fromElement` provides an opportunity to detect whether the `dragleave` event is actually escaping the drop target:

```typescript
onDragOver(event) {
  // this e.pD() is important to register for the other events
  event.preventDefault();
  setInDrag(true);
},
onDragLeave(event) {
  let fromAncestor = event.fromElement;
  while (fromAncestor = fromAncestor.parentNode) {
    if (fromAncestor === dropTarget) {
      return;
    }
  }
  setInDrag(false);
},
onDrop(event) {
  event.preventDefault();
  setInDrag(false);

  const fileList = event.dataTransfer.files;
  //…
},
```
Standardizing `fromElement` would improve the drag-and-drop API.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3c/uievents/issues/84#issuecomment-1749895697
You are receiving this because you are subscribed to this thread.

Message ID: <w3c/uievents/issues/84/1749895697@github.com>

Received on Friday, 6 October 2023 02:20:31 UTC