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
2 Answers
Reset to default 1try 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条)