Javascript – Global override of mouse cursor with JavaScript

csshtmljavascriptmouse-cursor

In my web application I try to implement some drag and drop functionality. I have a global JavaScript component which does the the basic stuff. This object is also responsible for changing the mouse cursor, depending of the current drag operation (move, copy, link). On my web page there are various HTML elements which define an own cursor style, either inline or via a CSS file.

So, is there a way for my central drag and drop component to change the mouse cursor globally, independent from the style of the element the mouse cursor is over?

I tried:

document.body.style.cursor = "move"

and

document.body.style.cursor = "move !important"

But it doesn't work. Every time I drag over an element which defines a cursor style, the cursor changes to that style.

Sure, I could change the style of the element I'm currently dragging over, but then I have to reset it when I leave the element. This seems a little bit to complicated. I'm looking for a global solution.

Best Answer

Please: don't massacre your CSS!

To implement a drag and drop functionality, you have to use a very important API: element.setCapture(), which does the following :

  • All mouse events are redirected to the target element of the capture, regardless of where they occured (even outside the browser window)
  • The cursor will be the cursor of the target element of the capture, regardless where the mouse pointer is.

You have to call element.releaseCapture() or document.releaseCapture() to switch back to normal mode at the end of the operation.

Beware of a naïve implementation of drag and drop: you can have a lot of painful issues, like for example (among others): what happens if the mouse is released outside the browser's window, or over an element which has a handler that stops propagation. Using setCapture() solves all this issues, and the cursor style as well.

You can read this excellent tutorial that explains this in detail if you want to implement the drag and drop yourself.

Maybe you could also use jQuery UI draggable if possible in your context.