Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Firefox and IE how can change the cursor while dragging over different targets?

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?

like image 516
Kris Erickson Avatar asked Jun 02 '14 18:06

Kris Erickson


2 Answers

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.

like image 198
Larry Williamson Avatar answered Oct 21 '22 05:10

Larry Williamson


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('http://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;
}
like image 29
pschueller Avatar answered Oct 21 '22 06:10

pschueller