Javascript – HTML5 Drag and Drop effectAllowed and dropEffect

cursordrag and drophtmljavascriptjquery

The relationship between these two properties seems to have been the source of some confusion. Based on reading both the MDN site and MSDN I thought i had figured it out, but now I am not sure…

I figured that when an element is dragged, you can specify what is allowed to happen to it (i.e. it can be moved, copied, linked to – one of the effectAllowed constants). This is the effectAllowed property.

Different drop targets do different things, so when you dragover another element it can control which "effect" takes place on the drop, this is the "dropEffect" property. So I set up a simple example to test this theory out.

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();
});

I have a box the user can drag – the effects allowed are "copyMove". I have one box that sets dropEffect to copy, and once that sets dropEffect to move. What I expect is that when the user drags over the "copy box" the cursor will change to indicate a copy will happen, as I drag over the "move box" the cursor changes to indicate a move…

Only Chrome behaves as I would expect. Is this because the other browser are wrong or because I don't understand the spec. properly ?

UPDATE
Some more information from fiddling with this.

In both Firefox and Chrome, if you have a dragsource which indicates the effectAllowed is "copy" and a dropzone that says dropEffect is "move" then you cannot drop on the drop zone even if you cancel the event. I thought that dropEffect would be useful to read ondrop to see what to do, but it isn't available on Chrome, the dropEffect does not appear on the drop handler, e.g. trying to read the dataTransfer.dropEffect will say that the dropEffect is "none" even though you set it on dragover. Setting the dropEffect as noted above does influence the way the cursor is displayed.

On Firefox, the dropEffect does come through on the dropzone after being set on dragover, but it does not influence the display of the mouse cursor. On Firefox windows pressing the ctrl key does affect the display of the mouse, but does not affect the dropEffect property.

The spec shows that the source can listen for the dragend event to see what happened. It should look at the dropEffect within this event. Chrome, Mozilla and Safari work as you would hope here, the drop effect appears in the dragend event. In IE if the effect allowed is a simple value e.g. "copy" then any succesfull drop results in this value appearing as the dropEffect on dragend. If the effectAllowed was a compound value like copyMove and you tried to select "move" on dragover by setting the dropEffect, you're out of luck, that will come through as dropEffect = "none" at the source on dragend. You are stuck with one cursor & one dropEffect and that is the effectAllowed set on dragstart if that effect is a simple value. Interestingly the dropEffect it seems does come through when you drag into a native application from IE11 at least (and i assume earlier).

Other notes

On Safari on a mac – effectAllowed cannot be set programatically, therefore any dropEffect that gets set is valid. When you press the cmd key the effectAllowed becomes "move" and when you press the alt key the effectAllowed becomes "copy". Thereafter it works as you would hope, if the dropEffect is not one of these effectAlloweds the drop is not allowed by the browser.

More Info
I've been spending some spare time working on an HTML5 drag and drop library i wrote a bunch more about this and other issues in the docs for it, if you're interested please take a look at
the project

Best Answer

I checked ur fiddle and I have same response in chrome and IE 10, i.e. The cursor shows copy sign while dragging but it doesn't copy/move the rectangle. You can take help from http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop