在 HTML5 中拖动时如何更改光标图标?
Posted
技术标签:
【中文标题】在 HTML5 中拖动时如何更改光标图标?【英文标题】:How to change the cursor icon when dragging in HTML5? 【发布时间】:2015-07-15 03:16:14 【问题描述】:当用户拖动 DIV 时,我需要设置光标的图标(下例中为红色 div)。
我尝试了几次,包括使用 CSS cursor:move
和 event.dataTransfer.dropEffect
都没有成功,因为图标总是显示一个“交叉的圆圈”。
任何想法如何使用 html5 拖放 API 解决此问题?
http://jsbin.com/hifidunuqa/1/
<script>
window.app =
config:
canDrag: false,
cursorOffsetX: null,
cursorOffsetY: null
,
reset: function ()
this.config.cursorOffsetX = null;
this.config.cursorOffsetY = null;
,
start: function ()
document.getElementById('target').addEventListener('dragstart', function (event)
console.log('+++++++++++++ dragstart')
this.config.cursorOffsetX = event.offsetX;
this.config.cursorOffsetY = event.offsetY;
this.adjustPostion(event);
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.dropEffect = 'move';
.bind(this));
document.getElementById('target').addEventListener('drag', function (event)
console.log('+++++++++++++ drag')
this.adjustPostion(event);
.bind(this));
document.getElementById('target').addEventListener('dragend', function (event)
console.log('+++++++++++++ dragend')
this.reset();
.bind(this));;
,
adjustPostion: function (event)
if (event.pageX <= 0 || event.pageY <= 0)
console.log('skipped');
return;
var elm = document.getElementById('target');
elm.style.left = (event.pageX - this.config.cursorOffsetX) + 'px';
elm.style.top = (event.pageY - this.config.cursorOffsetY) + 'px';
console.log(event.pageX);
console.log(event.pageY);
;
</script>
【问题讨论】:
mousedown 事件呢? 是的 jquery 解决方案也可以。谢谢 @Pete 这行得通吗?该元素一直都有cursor: move !important;
样式。在拖动时添加这样的样式似乎不太可能改变行为。
@lharby 您的示例未使用 HTML5 拖放 API,这是此特定问题的根源。
@GibboK this may help you - 请参阅拖动属性部分。它显示您可以在拖动时添加自己的图标,但它似乎与禁止进入的圆圈一起使用(这可能是强制性的,因为它表明您不允许将对象放在您所在的位置)
【参考方案1】:
使用 mousedown 和 mousemove
window.app =
dragging: false,
config:
canDrag: false,
cursorOffsetX: null,
cursorOffsetY: null
,
reset: function ()
this.config.cursorOffsetX = null;
this.config.cursorOffsetY = null;
,
start: function ()
document.getElementById('target').addEventListener('mousedown', function (event)
console.log('+++++++++++++ dragstart');
this.dragging = true;
this.config.cursorOffsetX = event.offsetX;
this.config.cursorOffsetY = event.offsetY;
this.adjustPostion(event);
.bind(this));
document.getElementById('target').addEventListener('mousemove', function (event)
if (this.dragging)
console.log('+++++++++++++ drag');
event.target.style.cursor = 'move';
this.adjustPostion(event);
.bind(this));
document.getElementById('target').addEventListener('mouseup', function (event)
console.log('+++++++++++++ dragend');
this.dragging = false;
event.target.style.cursor = 'pointer';
this.reset();
.bind(this));
,
adjustPostion: function (event)
if (event.clientX <= 0 || event.clientY <= 0)
console.log('skipped');
return;
var elm = document.getElementById('target');
elm.style.left = (event.clientX - this.config.cursorOffsetX) + 'px';
elm.style.top = (event.clientY - this.config.cursorOffsetY) + 'px';
console.log(event.pageX);
console.log(event.pageY);
;
#target
position: absolute;
top: 100px;
left: 100px;
width: 400px;
height: 400px;
background-color: red;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
#ui1
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 400px;
background-color: blue;
z-index: 100;
#ui2
position: absolute;
top: 50px;
left: 550px;
width: 100px;
height: 400px;
background-color: green;
z-index: 100;
<!-- simulate -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body onload="window.app.start();">
<div id="ui1"></div>
<div id="ui2"></div>
<div id="target"></div>
</body>
</html>
【讨论】:
为什么需要控制光标偏移?该示例运行完美,但无法在我的应用中复制,不知道为什么。 确保元素不会跳转,因为当您单击元素时,您在元素内单击了它,并且您需要在元素内偏移光标位置。【参考方案2】:您真的需要Drag
API 吗?我发现我正在使用Drag
API,因为我在鼠标事件的可靠性方面遇到了问题(例如,mouseups
未被捕获)。
Drag
API 仅用于拖放功能,而且,如果您只是在摆弄单击和指向事件的可靠性,则可以使用新的 API .setPointerCapture
来处理这些情况有效。这是实现这一目标的最小可行方法:
el.onpointerdown = ev =>
el.onpointermove = pointerMove
el.setPointerCapture(ev.pointerId)
pointerMove = ev =>
console.log('Dragged!')
el.onpointerUp = ev =>
el.onpointermove = null
el.releasePointerCapture(ev.pointerId)
您可以完全控制光标的显示样式。
【讨论】:
这应该是公认的答案。确实是一个漂亮的解决方案。 很好的建议【参考方案3】:我不关心特定的光标,我只是想摆脱“交叉圆圈”的光标。我的解决方案是将 dragover 事件(具有以下功能)包含到所有已经具有 dragenter、dragstart 和 dragend 事件的元素中。
function dragover(event)
event.dataTransfer.dropEffect = "move";
event.preventDefault();
【讨论】:
【参考方案4】:添加event.dataTransfer.setData();
应该可以解决问题。一旦元素被识别为可拖动,浏览器将在您拖动时自动添加移动光标。当然,您必须删除所有其他 cursor: move
声明才能看到光标在拖动时发生变化。
小例子:
document.getElementById('target').addEventListener('dragstart', function (event)
event.dataTransfer.setData( 'text/plain', '' );
.bind(this));
如果您仍想更改图标(例如,使用自定义拖动图标),您可以使用 event.target.style.cursor
访问元素样式。
有关更多信息,请参阅MDN Drag & Drop 和 MDN Recommended Drag Types
【讨论】:
不幸的是,这似乎不起作用。使用 event.target.style.cursor='none';不改变光标。您能否将您的解决方案应用于我的 jsfiddle 并将链接发送给我?谢谢 老实说,我不再完全确定您要做什么。如果您的目标是在拖动过程中更改/删除图标,我不知道这是否可能。似乎 CSS 更改仅影响未拖动的元素。有几个指点:***.com/questions/6079346/…developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations 正确,我需要在使用 HTML5 拖放 API 的拖动过程中更改图标。感谢您抽出宝贵时间。以上是关于在 HTML5 中拖动时如何更改光标图标?的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 Drag & Drop 在拖动时更改光标(不要使用 UI)
如何将 HTML5 <canvas> 保存为 ICO 图像(图标文件)或 .cur 文件(静态鼠标光标)而不是 JavaScript 中的 PNG?