HTML5 drag and drop events - dragLeave fires before frame

When dragging, the dragLeave event sometimes fires before the drop event.

This causes problems because the target gets listeners in dragEnter with dragLeave and removes listeners. If dragLeave fires before the frame, then there is no listener for the drop.

I think the reason has something to do with another opposite intuitive: dragEnter sometimes fires several times for the same purpose, even when propagating. With a few dragEnters, it would be possible to create drops, while others would spawn dragLeave. If so, maybe I could associate dragLeave with dragEnter, but I don't see any means for this coordination.

function dragEnter( e ) {

  e.stopPropatation();

  // is multiple fires of dragEnter for same cell
  if( curCell == this ) return;

  curCell = this;
  curCell.addEventListener( 'drop', drop, true );
  curCell.addEventListener( 'dragover', dragOver, true );
  curCell.addEventListener( 'dragleave', dragLeave, true );

  ...
}

function dragLeave( e ) {
  e.stopPropagation();
  curCell.removeEventListener( 'drop', drop, true );
  curCell.removeEventListener( 'dragover', dragOver, true );
  curCell.removeEventListener( 'dragleave', dragLeave, true );
}
function drop( e ) {
  // do the actual work
  dragLeave( e );
}

Here is the call list:

begin drag dragstart
drag enter:  this=e9 - e.target=IMG
drag enter:  this=e9 - e.target=TD
drag enter:  this=e8 - e.target=TD
drag enter:  this=e8 - adding listeners
drag enter:  this=e8 - e.target=IMG
drag leave: this=e8
clearing listeners: this=e8

" " , :

drop: this=e8
+5
2

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}

function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}

function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<p>Drag  it</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">

</body>
</html>
+1

.

drop, dragover, dragleave dragenter, ?

HTML dnd api , . , - ,

onDragOver=function(e) { e.stopPropagation() }
onDrop=function(e) { /* handle drop */ }

, .

0

All Articles