ユーザーが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と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>
event.dataTransfer.setData();
を追加すると、問題が解決するはずです。要素がドラッグ可能として認識されると、ブラウザはドラッグすると移動カーソルを自動的に追加します。もちろん、ドラッグ中にカーソルが変化するのを確認するには、他のすべてのcursor: move
宣言を削除する必要があります。
最小限の例:
document.getElementById('target').addEventListener('dragstart', function (event) {
event.dataTransfer.setData( 'text/plain', '' );
}.bind(this));
アイコンを変更したい場合(カスタムドラッグアイコンを使用する場合など)、event.target.style.cursor
を使用して要素スタイルにアクセスできます。
詳細については、 MDNドラッグアンドドロップ および MDN推奨ドラッグタイプ を参照してください。
実際に必要Drag
APIですか?マウスイベントの信頼性に問題があるため(Drag
がキャプチャされないなど)、mouseups
APIを使用していることがわかりました。
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)
}
美しく、カーソルの表示スタイルを完全に制御できます。
特定のカーソルについては気にしませんでしたが、「クロスサークル」カーソルを削除したかっただけです。私の解決策は、すべての要素にdragoverイベント(次の関数を含む)を含めることで、これには既にdragenter、dragstart、およびdragendイベントがありました。
function dragover(event)
{
event.dataTransfer.dropEffect = "move";
event.preventDefault();
}