在拖放操作中,dragLeave事件有时会在drop事件之前触发。这会导致问题,因为目标在dragEnter中获取了监听器,而dragLeave和drop则移除了这些监听器。如果dragLeave在drop之前触发,则没有监听器用于drop。
我认为原因与另一个违反直觉的事情有关:即使关闭传播,dragEnter有时也会多次针对同一目标触发。有多个dragEnter时,其中一个将引发drop,而其他dragEnter将引发dragLeave。如果是这种情况,也许我可以将dragLeave与dragEnter关联起来,但我看不到协调的方法。
如果没有执行“清除监听器”,下一步将是:
我认为原因与另一个违反直觉的事情有关:即使关闭传播,dragEnter有时也会多次针对同一目标触发。有多个dragEnter时,其中一个将引发drop,而其他dragEnter将引发dragLeave。如果是这种情况,也许我可以将dragLeave与dragEnter关联起来,但我看不到协调的方法。
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 );
}
以下是调用列表:
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