26

I have a div which contains a span that is 16x16px. I want the drag event to start when user clicks and drags this icon but it should drag the whole div. I'm trying to follow this tutorial here: http://www.html5rocks.com/en/tutorials/dnd/basics/

I cant figureout how to do this with a handle. Please adivise.

Noitidart
  • 35,443
  • 37
  • 154
  • 323

2 Answers2

32

Here's a working example: https://jsfiddle.net/pwt1cbjc/

var draggable = document.getElementById('draggable');
var handle = document.getElementById('handle');
var target = false;
draggable.onmousedown = function(e) {
    target = e.target;
};
draggable.ondragstart = function(e) {
    if (handle.contains(target)) {
        e.dataTransfer.setData('text/plain', 'handle');
    } else {
        e.preventDefault();
    }
};
#draggable {
    width: 100px;
    height: 100px;
    border: 1px solid black;
}
#handle {
    width: 0;
    height: 0;
    border-right: 20px solid transparent;
    border-top: 20px solid black;
    cursor: move;
}
<h1>Drag Handle</h1>

<div id="draggable" draggable="true">
    <div id="handle">
    </div>
</div>
Orkhan Alikhanov
  • 9,122
  • 3
  • 39
  • 60
SaphuA
  • 3,092
  • 3
  • 39
  • 58
  • Wow thank you this is cool, the div is not moved though on drop, is it possible to add that? Also is it possible to add slide animation as user moves around? – Noitidart Jun 23 '15 at 15:24
  • 1
    Didn't expect you still needed an answer for this old question, haha! Came across it by accident and decided to answer it anyway. About dropping, take a look at the answer here for some sample code: http://stackoverflow.com/questions/6230834/html5-drag-and-drop-anywhere-on-the-screen – SaphuA Jun 24 '15 at 07:18
  • I went about it another way, it was much more intensive (on mousedown i added mousemove listener, and on mousemove i would set the elment `left`,`top` and it followed the cursor in nice animated way), your way is very nice and i feel more performant, and I would love to adapt it. – Noitidart Jun 24 '15 at 14:17
  • 2
    This is a good solution if you don't care about copy/paste of any content within the dragged tile. If you do care about that then this version isn't for you. – kamelkev May 24 '16 at 17:01
  • Pay Attention for this to work the selected item must be direct child of draggable element not `n+2` child – Seyed Hussein Mirzaki Jul 13 '22 at 15:04
29

I have slightly modified SaphuA's answer to allow highlighting text.

The trick is not to add the draggable attribute until the drag handle gets the mousedown event.

Here's a demo: https://jsfiddle.net/a6tgy9so/1/

Gorse horse
  • 5,093
  • 1
  • 20
  • 14
  • Oo that was an important note to share. Accepted this answer instead. Thanks for sharing! – Noitidart Jul 06 '18 at 21:21
  • great idea! Kudos to @SaphuA for the original idea too – Juan Stoppa Feb 08 '19 at 12:06
  • There is a bug when you click on the handle (not move it, just click), then `draggable` attribute remains `true`. – Traxo Apr 12 '19 at 08:46
  • 1
    @Traxo I've updated the demo, there's now a mouseup handler to prevent this – Gorse horse Apr 15 '19 at 14:37
  • Works great except could you please add how to actually drop the window to where you dragged it to? I have an ondrop event on a surrounding BODY element, but can't get the window to move to exactly where I dropped it. – user1343035 Dec 02 '19 at 04:01
  • 1
    @user1343035 In that case you need to change the CSS position of the dragged element. See [this example from MDN that I modified](https://jsfiddle.net/zsLkme7g/2/) (the [original is here](https://developer.mozilla.org/en-US/docs/Web/API/Document/drop_event)) – Gorse horse Dec 02 '19 at 14:47