这两个属性之间的关系似乎是一些混乱的根源。基于阅读MDN 网站 和 MSDN,我以为我已经弄清楚了,但现在我不确定......
我认为当拖动一个元素时,您可以指定允许发生的情况(即它可以移动、复制、链接到 -
effectAllowed
常量之一)。这是 effectAllowed
属性。
不同的放置目标会执行不同的操作,因此当您拖动另一个元素时,它可以控制放置时发生的“效果”,这就是“dropEffect”属性。所以我设置了一个简单的例子来测试这个理论。
$("[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 为“复制”,并且拖放区指示 dropEffect 为“移动”,那么即使您取消该事件,也无法将其拖放到拖放区域上。我认为 dropEffect 对于读取 ondrop 来查看要做什么很有用,但它在 Chrome 上不可用,dropEffect 不会出现在 drop 处理程序上,例如尝试读取 dataTransfer.dropEffect 会说 dropEffect 为“无”,即使您将其设置为拖拽。如上所述设置 dropEffect 确实会影响光标的显示方式。
在 Firefox 上,拖放设置后,dropEffect 确实会在拖放区域中生效,但它不会影响鼠标光标的显示。在 Firefox 窗口中按 ctrl 键确实会影响鼠标的显示,但不会影响 dropEffect 属性。
规范显示源可以监听 Dragend 事件以查看发生了什么。它应该查看此事件中的 dropEffect。 Chrome、Mozilla 和 Safari 的工作方式正如您所希望的那样,拖放效果出现在拖尾事件中。在 IE 中,如果允许的效果是一个简单的值,例如“复制”,那么任何成功的放置都会导致该值在拖尾上显示为 dropEffect。如果effectAllowed是像copyMove这样的复合值,并且您尝试通过设置dropEffect在dragover上选择“移动”,那么您就不走运了,这将在dragend的源代码中显示为dropEffect =“none”。您被困在一个光标和一个 dropEffect 上,如果该效果是一个简单值,则这就是在 Dragstart 上设置的effectAllowed。有趣的是,当您至少从 IE11 拖入本机应用程序时,dropEffect 似乎确实会出现(我假设之前)。其他注意事项
在 Mac 上的 Safari 上 -effectAllowed 无法以编程方式设置,因此设置的任何 dropEffect 都是有效的。当您按 cmd 键时,effectAllowed 变为“移动”,当您按 alt 键时,effectAllowed 变为“复制”。此后,如果 dropEffect 不是这些effectAlloweds之一,则它会按照您希望的方式工作。浏览器不允许放置。
更多信息 我花了一些业余时间研究 HTML5 拖放库,我在文档中写了很多关于这个问题和其他问题的内容,如果您有兴趣,请看一下 项目