HTML5拖放effectAllowed和dropEffect

这两个属性之间的关系似乎是一些混乱的根源。 基于读取MDN站点和MSDN,我以为我已经弄明白了,但现在我不确定….

我想当拖动一个元素时,你可以指定允许它发生的事情(即它可以移动,复制,链接到 – effectAllowed常量之一)。 这是effectAllowed属性。

不同的放置目标会做不同的事情,所以当你开辟另一个元素时,它可以控制在drop上发生的“效果”,这就是“dropEffect”属性。 所以我设置了一个简单的例子来测试这个理论。

的jsfiddle

$("[draggable='true']").on("dragstart", function(e) { var dt = e.originalEvent.dataTransfer; dt.effectAllowed = "copyMove"; dt.setData("text/plain", "Foo"); }); $("#dropZoneCopy").on("dragover", function(e) { var dt = e.originalEvent.dataTransfer; dt.dropEffect = "copy"; e.preventDefault(); }); $("#dropZoneMove").on("dragover", function(e) { var dt = e.originalEvent.dataTransfer; dt.dropEffect = "move"; e.preventDefault(); }); 

我有一个用户可以拖动的框 – 允许的效果是“copyMove”。 我有一个框设置dropEffect复制,一旦设置dropEffect移动。 我期望的是,当用户拖过“复制框”时,光标将改变以指示将发生复制,因为我在“移动框”上拖动光标变化以指示移动…

只有Chrome的行为符合我的预期。 这是因为其他浏览器是错误的还是因为我不了解规范。 好吗?

更新来自摆弄这个的更多信息。

在Firefox和Chrome中,如果你有一个表明effectAllowed是“复制”的dragsource和一个dropEffect表示“移动”的dropzone,那么即使取消该事件你也不能放弃掉落区域。 我认为dropEffect对于阅读ondrop看看该做什么很有用,但它在Chrome上不可用,dropEffect不会出现在drop handler上,例如尝试读取dataTransfer.dropEffect会说dropEffect是“没有“即使你把它放在dragover上。 如上所述设置dropEffect确实会影响光标的显示方式。

在Firefox上,dropEffect在dragover上设置后会在dropzone上通过,但它不会影响鼠标光标的显示。 在Firefox窗口上按ctrl键确实会影响鼠标的显示,但不会影响dropEffect属性。

规范显示源可以监听dragend事件以查看发生的情况。 它应该查看此事件中的dropEffect。 Chrome,Mozilla和Safari正如您所希望的那样工作,dragend效果出现在dragend事件中。 在IE中,如果允许的效果是一个简单的值,例如“复制”,则任何成功的下降都会导致此值显示为drand上的dropEffect。 如果effectAllowed是一个像copyMove这样的复合值,并且你试图通过设置dropEffect选择“移动”dragover,那么你运气不好,这将在dragend的源头上以dropEffect =“none”的forms出现。 你被一个光标和一个dropEffect困住,如果该效果是一个简单的值,那就是在dragstart上设置的effectAllowed。 有趣的是,当你从IE11至少拖入一个本机应用程序(我之前假设)时,它似乎确实会出现dropEffect。

其他说明

在Mac上的Safari上 – 无法以编程方式设置effectAllowed,因此任何设置的dropEffect都是有效的。 当您按下cmd键时,effectAllowed变为“move”,当您按下alt键时,effectAllowed变为“copy”。 此后它可以正常工作,如果dropEffect不是这些effectAlloweds中的一个,则浏览器不允许删除。

更多信息我花了一些时间在HTML5拖放库上工作我在文档中写了更多关于这个问题和其他问题,如果你有兴趣请看看项目

我检查了你的小提琴,我在chrome和IE 10中有相同的响应,即光标在拖动时显示复制符号,但它不复制/移动矩形。 您可以从http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop获取帮助

我知道这不是最好的答案,但你可以使用像JQUERY UI这样的UI框架,它已经内置了拖放function和一系列function。 可能比重建function更好。