javascript - HTML5 drag and drop events - dragLeave fires before drop - Stack Overflow

In drag and drop the dragLeave event sometimes fires before the drop event.This is causing problems bec

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

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
Share Improve this question edited Nov 6, 2019 at 20:41 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Apr 2, 2011 at 6:42 cc youngcc young 20.3k32 gold badges95 silver badges150 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 1

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>

There's rarely a reason to manage your event listeners in this way.

If you bind to drop, dragover, dragleave at the same time as you bind to dragenter do you still see the problem?

The HTML dnd api is a little bit weird when you first look at it. Depending on what you are trying to do something simple like

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

may be all the listeners you need.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745107091a4611624.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信