javascriptcssdrag-and-dropweb-componentslot

Can't drag element, by clicking on the slotted text (Vanilla JS)


I created a draggable Web-Component with a slot:

const DragItemTemplate = document.createElement("template");
DragItemTemplate.innerHTML =
  `<style>` +
    `div{` +
      `background: gray;` +
      `width: 200px;` +
      `height: 50px;` +
      `padding: 5px;` +
      `margin: 5px;` +
      `cursor: move;` +
      `display: flex;` +
      `align-items: center;` +
      `justify-content: center;` +
    `}` +
  `</style>` +
  `<div draggable="true">` +
    `<slot></slot>` +
  `</div>`;

class DragItem extends HTMLElement {
  constructor() {
    super();

    this.attachShadow({mode: "open"});
    this.shadowRoot.appendChild(DragItemTemplate.content.cloneNode(true));
  }
}

window.customElements.define("drag-item", DragItem);
<!DOCTYPE html>
<html lang="en">

<body>
  <drag-item></drag-item>
  <drag-item>Slotted Text</drag-item>
</body>

</html>

When I start dragging the component by clicking into the component (not the text) everything works as it should. But when I try to drag it by clicking on the text (slot) it doesn't work.

What could I do to make the whole component (including the text) draggable?


Solution

  • Set slot { pointer-events:none } so nothing in the <slot> triggers a mouse event, and thus your <div draggable captures the drag

    <drag-item></drag-item>
    <drag-item>Slotted Text</drag-item>
    <drag-item><div>Slotted Text</div></drag-item>
    
    <script>
    customElements.define("drag-item", class extends HTMLElement {
      constructor() {
        super()
          .attachShadow({mode:"open"})
          .innerHTML =
          `<style>` +
          `div{` +
            `background: gray;` +
            `width: 200px;` +
            `height: 50px;` +
            `padding: 5px;` +
            `margin: 5px;` +
            `cursor: move;` +
            `display: flex;` +
            `align-items: center;` +
            `justify-content: center;` +
          `}` +
          `slot{pointer-events:none}` + // <---------------
          `</style>` +
          `<div draggable="true">` +
            `<slot></slot>` +
          `</div>`;
      }
    });
    </script>