118

It seems the drop event is not triggering when I would expect.

I assume that the drop event fires when an element that is being dragged is releases above the target element, but this doesn't seem to the the case.

What am I misunderstanding?

http://jsfiddle.net/LntTL/

$('.drop').on('drop dragdrop',function(){
    alert('dropped');
});
$('.drop').on('dragenter',function(){
    $(this).html('drop now').css('background','blue');
})
$('.drop').on('dragleave',function(){
    $(this).html('drop here').css('background','red');
})
Axel
  • 3,331
  • 11
  • 35
  • 58
Mild Fuzz
  • 29,463
  • 31
  • 100
  • 148
  • 1
    duplicate question: http://stackoverflow.com/questions/19223352/jquery-ondrop-not-firing/36207641#36207641 – bob Mar 24 '16 at 18:43
  • 1
    potential answer: http://stackoverflow.com/questions/8414154/html5-drop-event-doesnt-work-unless-dragover-is-handled – bob Mar 24 '16 at 18:43

4 Answers4

243

In order to have the drop event occur on a div element, you must cancel the ondragenter and ondragover events. Using jquery and your code provided...

$('.drop').on('drop dragdrop',function(){
    alert('dropped');
});
$('.drop').on('dragenter',function(event){
    event.preventDefault();
    $(this).html('drop now').css('background','blue');
})
$('.drop').on('dragleave',function(){
    $(this).html('drop here').css('background','red');
})
$('.drop').on('dragover',function(event){
    event.preventDefault();
})

For more information, check out the MDN page.

idmean
  • 14,540
  • 9
  • 54
  • 83
iamchris
  • 2,621
  • 1
  • 16
  • 15
68

You can get away with just doing an event.preventDefault() on the dragover event. Doing this will fire the drop event.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Michael Falck Wedelgård
  • 2,943
  • 1
  • 27
  • 39
  • 6
    that has an uncovered edge case, you must call e.preventDefault() on dragenter too, see my other comment – zupa Nov 23 '17 at 12:22
13

In order for the drop event to fire, you need to assign a dropEffect during the over event, otherwise the ondrop event will never get triggered:

$('.drop').on('dragover',function(event){
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';  // required to enable drop on DIV
})
// Value for dropEffect can be one of: move, copy, link or none
// The mouse icon + behavior will change accordingly.
bob
  • 7,539
  • 2
  • 46
  • 42
  • 13
    Actually you need to do `event.originalEvent.dataTransfer.dropEffect = "copy"` because jQuery uses its own `event` – AymKdn Dec 10 '16 at 20:57
  • This solution worked for me. After doing work around on this issue, i think think this is necessary to prevent the default behavior of dragover event. – Çh Furqan Hämëèd Jūtt May 01 '23 at 11:03
1

This isn't an actual answer but for some people like me who lack the discipline for consistency. Drop didn't fire for me in chrome when the effectAllowed wasnt the effect I had set for dropEffect. It did however work for me in Safari. This should be set like below:

ev.dataTransfer.effectAllowed = 'move';

Alternatively, effectAllowed can be set as all, but I would prefer to keep specificity where I can.

for a case when drop effect is move:

ev.dataTransfer.dropEffect = 'move';

jjczopek
  • 3,319
  • 2
  • 32
  • 72