I have an HTML page which has some draggable elements. Our specs say that hovering mouse on such element the cursor must be grab
, and during drag cursor must be grabbing
.
I know it is possible to set dropEffect
which changes cursor appearance above drop zone, but there are very little options: copy
, move
, link
, and none
-- no custom or alike.
I have tried to change cursor with Javascript and CSS, like setting cursor: grabbing;
when ondragstart
is fired. But browser default move cursor appears instead when dragging on drop zone.
So the question is: What am I missing to show grabbing cursor () during drag?
Unfortunately I cannot use JQuery or other helping libraries in the solution. Thanks in advance!
var onDragStart = function(event) { event.dataTransfer.setData("Text", event.target.id); event.currentTarget.classList.add("being-dragged"); }; var onDragEnd = function(event) { event.currentTarget.classList.remove("being-dragged"); }; var onDragOver = function(event) { event.preventDefault(); };
.dropzone { width: 500px; height: 200px; background-color: silver; } .block { position: absolute; background-color: pink; margin: 10px; border: 20px solid pink; } .draggable { cursor: -webkit-grab; cursor: grab; } .being-dragged { cursor: -webkit-grabbing; cursor: grabbing; background-color: red; }
<div class = "dropzone" ondragover = "onDragOver(event);" > Grab and drag block around <div class = "draggable block" draggable = "true" ondragstart = "onDragStart(event);" ondragend = "onDragEnd(event);" > I'm draggable </div> </div>
5 Answers
Answers 1
It is a known issue reported here
While dragging, the cursor will automatically changed to normal.
My tries gave me the following. Gave an active
on the element with grabbing cursor. While it is active, the cursor will change but once you start the drag, it will change automatically.
I tried to set body
cursor to grabbing on dragstart but no result. Even it is not working.
var onDragStart = function(event) { event.dataTransfer.setData("Text", event.target.id); event.currentTarget.classList.add("being-dragged"); }; var onDragEnd = function(event) { event.currentTarget.classList.remove("being-dragged"); }; var onDragOver = function(event) { event.preventDefault(); };
.dropzone { width: 500px; height: 200px; background-color: silver; } .block { position: absolute; background-color: pink; margin: 10px; border: 20px solid pink; } .draggable { cursor: -webkit-grab; cursor: grab; } .draggable:active{ cursor : -moz-grabbing; cursor: -webkit-grabbing; cursor: grabbing; } .being-dragged{ background-color: red; cursor : -moz-grabbing; cursor: -webkit-grabbing; cursor: grabbing; }
<div class = "dropzone" ondragover = "onDragOver(event);" > Grab and drag block around <div class = "draggable block" draggable = "true" ondragstart = "onDragStart(event);" ondragend = "onDragEnd(event);" > I'm draggable </div> </div>
Answers 2
I know just a little bit about draggable elements with pure JavaScript
and I'm sorry that I can't explain the following.
The problem was that the onDragEnd
never get fired so I've searched something and find this example with draggable elements.
Now, if you change the function of the onDragStart
event it will work but I think you have to change the cursor in another way like to change the class of the body onDragStart
var onDragStart = function(event) { event.dataTransfer.setData("Text", event.target.id); event.currentTarget.classList.add("being-dragged"); };
All in one
var onDragStart = function(event) { event.dataTransfer.setData("Text", event.target.id); event.currentTarget.classList.add("being-dragged"); }; var onDragEnd = function(event) { event.currentTarget.classList.remove("being-dragged"); }; var onDragOver = function(event) { event.preventDefault(); };
.dropzone { width: 500px; height: 500px; background-color: silver; } .block { width: 200px; height: 50px; background-color: pink; } .draggable1 { cursor: -webkit-grab; cursor: grab; } .being-dragged { cursor: -webkit-grabbing; cursor: grabbing; background-color: red; }
<div class="dropzone" ondragover="onDragOver(event);"> <div class="draggable1 block" draggable="true" ondragstart="onDragStart(event);" ondragend="onDragEnd(event);"> I'm draggable </div> </div>
Answers 3
Try this ! It works for me !
.draggable { cursor: -webkit-grab; cursor: grab; } .draggable:active { cursor: -webkit-grabbing; cursor: grabbing; }
Answers 4
I spent sometime to find solution for this, ended with this trick. I feel this is best way less code and apt work.
.drag{ cursor: url('../images/grab.png'), auto; } .drag:active { cursor: url('../images/grabbing.png'), auto; }
Answers 5
It seems that browsers don't allow changing the cursor at the beginning of a drag & drop operation. I don't know why but it's a known issue, I believe they will in the future.
If jQuery is not an option, a possible way around is to implement a drag & drop from scratch, using mouse events and cloning the source element:
var onDragStart = function (event) { event.preventDefault(); var clone = event.target.cloneNode(true); clone.classList.add("dragging"); event.target.parentNode.appendChild(clone); var style = getComputedStyle(clone); clone.drag = { x: (event.pageX||(event.clientX+document.body.scrollLeft)) - clone.offsetLeft + parseInt(style.marginLeft), y: (event.pageY||(event.clientY+document.body.scrollTop)) - clone.offsetTop + parseInt(style.marginTop), source: event.target }; }; var onDragMove = function (event) { if (!event.target.drag) {return;} event.target.style.left = ((event.pageX||(event.clientX+document.body.scrollLeft)) - event.target.drag.x) + "px"; event.target.style.top = ((event.pageY||(event.clientY+document.body.scrollTop)) - event.target.drag.y) + "px"; }; var onDragEnd = function (event) { if (!event.target.drag) {return;} // Define persist true to let the source persist and drop the target, otherwise persist the target. var persist = true; if (persist || event.out) { event.target.parentNode.removeChild(event.target); } else { event.target.parentNode.removeChild(event.target.drag.source); } event.target.classList.remove("dragging"); event.target.drag = null; }; var onDragOver = function (event) { event.preventDefault(); };
.dropzone { width: 500px; height: 200px; background-color: silver; } .block { position: absolute; background-color: pink; margin: 10px; border: 20px solid pink; } .draggable { position: absolute; cursor: pointer; /* IE */ cursor: -webkit-grab; cursor: grab; } .dragging { cursor: -webkit-grabbing; cursor: grabbing; background-color: red; }
<div class="dropzone" onmouseover="onDragOver(event);"> Grab and drag block around <div class = "draggable block" onmousedown = "onDragStart(event);" onmousemove = "onDragMove(event);" onmouseup = "onDragEnd(event);" onmouseout = "event.out = true; onDragEnd(event);" > I'm draggable </div> </div>
0 comments:
Post a Comment