自定义光标,无需库即可拖放 HTML 元素

2024-04-30

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.

我知道可以设置dropEffect https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect这会更改放置区域上方的光标外观,但选项很少:copy, move, link, and none -- no custom或类似的。

我尝试用 Javascript 和 CSS 更改光标,例如设置cursor: grabbing; when ondragstart被解雇了。但在拖放区域上拖动时,会出现浏览器默认的移动光标。

So the question is: What am I missing to show grabbing cursor (grabbing) during drag?

不幸的是,我无法在解决方案中使用 JQuery 或其他帮助库。提前致谢!

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>

浏览器似乎不允许在拖放操作开始时更改光标。我不知道为什么,但这是一个已知的问题,我相信他们将来会的。

如果 jQuery 不是一个选项,一种可能的解决方法是从头开始实现拖放,使用鼠标事件并克隆源元素:

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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义光标,无需库即可拖放 HTML 元素 的相关文章

随机推荐