javascript 在 HTML5 中拖动时如何更改光标图标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30052111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change the cursor icon when dragging in HTML5?
提问by GibboK
I need to set the icon for cursor when a user is dragging DIV (red div in the following example).
当用户拖动 DIV 时,我需要为光标设置图标(以下示例中为红色 div)。
I have tried several attempt, including using CSS cursor:move
and event.dataTransfer.dropEffect
with no success, as the icon always show up a "crossed circle".
我尝试了好几种尝试,包括使用CSScursor:move
和 event.dataTransfer.dropEffect
没有成功,因为图标总是显示了一个“十字圆”。
Any ideas how to solve this issue using HTML5 drag-and-drop API?
任何想法如何使用 HTML5 拖放 API 解决此问题?
http://jsbin.com/hifidunuqa/1/
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>
采纳答案by Ihsan
use mousedown and mousemove
使用 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>
回答by Ihsan
Adding event.dataTransfer.setData();
should solve the problem. Once the element is recognized as draggable the browser will add a move cursor automatically once you drag. Of course, you will have to remove all other cursor: move
declarations to see the cursor changing while dragging.
添加event.dataTransfer.setData();
应该可以解决问题。一旦元素被识别为可拖动,浏览器将在您拖动时自动添加移动光标。当然,您必须删除所有其他cursor: move
声明才能看到拖动时光标的变化。
Minimal example:
最小的例子:
document.getElementById('target').addEventListener('dragstart', function (event) {
event.dataTransfer.setData( 'text/plain', '' );
}.bind(this));
If you still want to change the icon (e.g. to use a custom drag icon), you could access the element style using event.target.style.cursor
.
如果您仍想更改图标(例如使用自定义拖动图标),您可以使用 访问元素样式event.target.style.cursor
。
For more info see MDN Drag & Dropand MDN Recommended Drag Types
有关更多信息,请参阅MDN 拖放和MDN 推荐的拖放类型
回答by nikk wong
Do you actually needthe Drag
API? I found that I was using the Drag
API because I was having trouble with the reliability of mouse events (mouseups
not being captured, for example).
你真的需要的Drag
API?我发现我在使用Drag
API 是因为我在鼠标事件的可靠性方面遇到了问题(mouseups
例如,没有被捕获)。
The Drag
API is only for drag-and-drop functionality, and, if you're simply fiddling with the reliability of your clicking and pointing events, a new API, .setPointerCapture
is made to handle these cases more effectively. Here's the minimal viable way to achieve this:
该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)
}
Beautifully, you will maintain full control over your cursor's display style.
美妙的是,您将保持对光标显示样式的完全控制。
回答by mikiqex
I didn't care about a particular cursor, I just wanted to get rid of the "crossed circle" one. My solution was to include dragoverevent (with following function) to all elements, that already had dragenter, dragstart and dragend events.
我不关心特定的光标,我只是想摆脱“交叉圆圈”的光标。我的解决方案是将dragover事件(具有以下功能)包含到所有已经具有 dragenter、dragstart 和 dragend 事件的元素中。
function dragover(event)
{
event.dataTransfer.dropEffect = "move";
event.preventDefault();
}