Skip to content

dragstart prevention does not work within shadow dom #1065

@ColonelThirtyTwo

Description

@ColonelThirtyTwo

In install, the dragstart event is silenced via this:

  scope.interactions.docEvents.push({
    type: 'dragstart',
    listener(event) {
      for (const interaction of scope.interactions.list) {
        if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {
          interaction.interactable.checkAndPreventDefault(event);
          return;
        }
      }
    }
  });

However, if a draggable is added to an element inside of a web component's shadow dom, the event's target will be the web component itself, which will fail the nodeContains check. Then, the browser's drag behavior will continue and emit a pointercancel event, effectively immediately canceling the draggable right after it starts.

Ideally draggable.js should attach the listener to the element itself, which will have access to the internals for closed shadow dom components. An easier fix which only works for open shadow doms would be to check the first element of the composedPath to get the "real" element, but this will only work with open shadow doms.

As a workaround, you can manually implement your own drag cancellations on the draggable elements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions