14

Doing drag and drop in HTML5, I need to be able to change the cursor depending upon the drop target. In Chrome this works by changing the dropEffect,

 if (e.currentTarget.id == 'dropMove') {
     e.originalEvent.dataTransfer.dropEffect = 'move';
 } else {
     e.originalEvent.dataTransfer.dropEffect = 'link';
 }

however changing the dropEffect in IE and Firefox has no effect on the cursor. See the following Fiddle:

http://jsfiddle.net/ksoncan34/s7kN5/

I've tried manually setting the cursor, with window.cursor, but this also has no effect. How can I change the cursor for different drop targets in Firefox and IE?

Kris Erickson
  • 33,454
  • 26
  • 120
  • 175
  • Which operating system and browser versions are you using? – Tyler Eich Jun 07 '14 at 04:19
  • Windows 7 and 8.1, browsers are the latest Firefox (29.0.1) and IE 11. – Kris Erickson Jun 08 '14 at 04:15
  • 3
    I am using Ubuntu with latest Firefox, its working fine for both cursor. – lokeshpahal Jun 10 '14 at 04:08
  • It looks to me, that the effect must be set in dragStart and cannot be changed in dragover etc. Something in a sense, that the dragged item declares in what way its meant to be dragged and targets have no say in this. – Zee Jun 10 '14 at 06:33
  • 2
    Working fine in Firefox 29.0.1 and 25.0 on OS X 10.9.3. Sounds like this might be a Windows-only bug. – freshtop Jun 10 '14 at 17:45
  • 1
    Works on Xubuntu 14.04 with FF 29.0 and on Chromium (if this is of any relevance for you) it seems like the cursor changes only on the _drop move_ field not on the _drop link_ field. – slevon Jun 10 '14 at 21:14
  • Has anyone besides the OP reproduced this issue? It works fine in Firefox on my machine. – Sam Hanley Jun 11 '14 at 12:01
  • @sphanley I can confirm the OP's behavior on Win7SP1 w/ FF29.0.1. – user193130 Jun 11 '14 at 14:54
  • I reproduced the issue with IE11 and FF (Win7 x64). It works with Chrome. I tried to fix that yesterday... That is crazy, I don't get what is the "moveLink" effectAllowed for. If you finally can only have one effect! This is non sense. – M'sieur Toph' Jun 11 '14 at 15:30

3 Answers3

5

I'd suggest using jQuery ui -- droppable and draggable.

You can hide the default/actual cursor using cursor: none and use a stylized DOM element to render your own 'cursor' element.

I've provided an example here: http://jsfiddle.net/lawrencealan/WMyu7/78/ (updated 6/8/2017)

Note: mousemove stops firing during dragging of "draggable" attributed elements.

--

EDIT: As of September 2019, the example is now broken.

Larry Williamson
  • 1,149
  • 5
  • 18
  • Wish that the example wasn't built with jQueryUI as I don't want to have to build in that dependency, but turning the cursor off and creating a pseudo cursor is the best solution I have seen so far. Thanks. – Kris Erickson Jun 11 '14 at 20:02
  • Well, you can always use a customized jqueryui build that only has the `draggable` and `droppable` functionality, or implement that functionality on your own. Just have to keep track of the `mousedown`, `mousemove` and `mouseup` events... not to mention touch. I wasn't about to do that for the example... maybe when I'm bored one day ;) -- check out http://ramkulkarni.com/blog/simple-dragdrop-with-javascript-jquery/ – Larry Williamson Jun 14 '14 at 04:54
  • suggesting to use something else is not a valid answer in my opinion – dwp4ge May 06 '16 at 10:56
1

Unfortunately the support for cursor change on .dropeffect seems to be lacking.

You could try to attach an element to the mouse X and Y coords and manipulate that as it moves, but it can get messy. I think that lawrencealan's jQuery UI solution, which does just that, is probably the only reliable way to do this... and is actually quite simple. Still I would like to suggest an alternative which may suit your needs just as well, and does not require jQuery UI:

Alternative:

Instead of binding code to mousemove and dealing with unreliable cursor manipulations, I would suggest to simply have the targets change their appearance when you drag over them.

For example: jsfiddle

Add something like this to your dragover function:

$(this).addClass('draggedover');

Make sure to remove it on dragleave:

$('.drop').bind('dragleave', function (e) {
    $(this).removeClass('draggedover');
});

And then add some CSS to go along with it:

.draggedover::before {
    content: '';
    background-image: url('https://i.stack.imgur.com/czlkT.jpg');
    width: 40px;
    height: 40px;
    position: absolute;
    right: 0;
    top: 0;
    overflow: hidden;
}
#dropMove.draggedover::before {
    background-position: -110px -70px;
}

#dropLive.draggedover::before {
    background-position: -5px -10px;
}
Community
  • 1
  • 1
pschueller
  • 4,362
  • 2
  • 27
  • 50
0

I found this link while searching: https://connect.microsoft.com/IE/feedback/details/780585/dropeffect-not-working-properly-in-ie-standard-mode-ie9-ie10

Looks like Microsoft is rejecting this as working by design. What might help is the 3rd comment that suggest a way to fix the usability issue. He did not share any code though.

spaque99
  • 86
  • 3