Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom cursor with drag and drop an HTML element without libraries

I have an HTML page which has some draggable elements. Our specs say that hovering mouse on such element the cursor must be grab grab, and during drag cursor must be grabbing 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 (grabbing) 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>
like image 448
Travenin Avatar asked Jun 08 '17 23:06

Travenin


People also ask

How do I customize my cursor in HTML?

Answer: Use the CSS cursor property You can define a custom cursor using the CSS cursor property. The cursor property takes the comma-separated list of user-defined cursors value followed by the generic cursor. First of all create cursor image and save it with the extension .

Can any HTML element be draggable?

In HTML, any element can be dragged and dropped.

How do you drag an element in HTML?

HTML Drag and Drop (DnD) is a feature of HTML5. It is a powerful user interface concept which is used to copy, reorder and delete items with the help of mouse. You can hold the mouse button down over an element and drag it to another location. If you want to drop the element there, just release the mouse button.


2 Answers

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>
like image 85
Javier Rey Avatar answered Sep 22 '22 11:09

Javier Rey


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>
like image 21
Sagar V Avatar answered Sep 22 '22 11:09

Sagar V