Search code examples
javascripthtmldrag-and-dropcross-browserdraggable

Draggable button in Firefox


Is it possible to make a <button> (<input type="button">) work with HTML5 drag and drop in Mozilla Firefox (while still being clickable)?

The following snippet works in Google Chrome but the button and div with button cannot be dragged Mozilla Firefox (unless the Alt key is pressed down, no idea about mobile):

document.getElementById("myDiv").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myDiv")
  }
);

document.getElementById("myButton").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myButton")
  }
);

document.getElementById("myDivWithButton").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myDivWithButton")
  }
);
<div id="myDiv" draggable="true">Div</div>
<button id="myButton" draggable="true">Button</button>
<div id="myDivWithButton" draggable="true"><button>Div with Button</button></div>

I used draggable="true" and dataTransfer.setData, is there something I missed? Is there some sensible workaround?

(If you want to know what I need this for: I have something which can be either dragged at a certain position or set at the default position [center of current view], my idea was to do both through the button [d&d → choose position, click → default position]. I know that I guess I could try to format a <div> to make it look like a <button> or simply split the control into two elements but I'd rather not.)


Solution

  • I found a tricky solution:

    <label draggable="true" ondragstart="event.dataTransfer.setData('text/plain', '')">
        <input type="button" value="Click me!" style="pointer-events: none" onclick="console.log(event)">
    </label>

    Wrap input with a draggable label and set pointer-events CSS property to none. Using this method, your button will be interactive and draggable.