111

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,189
  • 11
  • 35
  • 56
Mild Fuzz
  • 27,845
  • 29
  • 97
  • 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

229

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,246
  • 8
  • 52
  • 81
iamchris
  • 2,481
  • 1
  • 15
  • 14
64

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

HoldOffHunger
  • 15,349
  • 8
  • 79
  • 115
Michael Falck Wedelgård
  • 2,771
  • 1
  • 24
  • 36
  • 5
    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
11

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
  • 6,861
  • 2
  • 44
  • 41
  • 11
    Actually you need to do `event.originalEvent.dataTransfer.dropEffect = "copy"` because jQuery uses its own `event` – AymKdn Dec 10 '16 at 20:57
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,259
  • 2
  • 31
  • 69