Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 drag and drop events - dragLeave fires before drop

In drag and drop the dragLeave event sometimes fires before the drop event.

This is causing problems because the target is getting the listeners in dragEnter with dragLeave and drop removing the listeners. If dragLeave fires before drop, then there is no listener for the drop.

I think the reason has something to do with another contra-intuitive: the dragEnter sometimes fires multiple times for the same target, even with propagation off. With multiple dragEnters, one would spawn a drop while the others would spawn a dragLeave. If this is the case, perhaps I could associate the dragLeave with the dragEnter - but I see no means of that 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's a list of calls:

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

If the "clearing listeners" were not performed, the next step would have been:

drop: this=e8
like image 908
cc young Avatar asked Nov 14 '22 01:11

cc young


1 Answers

try this

<!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>
like image 152
Shinto Joseph Avatar answered Jan 03 '23 08:01

Shinto Joseph