ドラッグ可能な要素を含むHTMLページがあります。私たちの仕様では、カーソルをそのような要素の上に置くとカーソルmustがgrab
、およびドラッグカーソル中must be grabbing
。
dropEffect
を設定して、ドロップゾーンの上にカーソルの外観を変更することは可能ですが、選択肢はほとんどありません:copy
、move
、link
、およびnone
-いいえcustomなど。
ondragstart
が発生したときにcursor: grabbing;
を設定するなど、JavaScriptとCSSでカーソルを変更しようとしました。ただし、ドロップゾーンでドラッグすると、ブラウザのデフォルトの移動カーソルが代わりに表示されます。
だから問題は次のとおりです:グラブカーソル( )ドラッグ中?
残念ながら、私はソリューションで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>
これは報告されている既知の問題です ここ
ドラッグ中、カーソルは自動的に通常に変わります。
私の試みは私に次のことを与えました。カーソルをつかんで要素にactive
を付けます。アクティブな間、カーソルは変化しますが、ドラッグを開始すると、カーソルは自動的に変化します。
body
カーソルをdragstartをつかむように設定しようとしましたが、結果がありませんでした。それでも機能しません。
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>
私はこれを理解しようとして多くの苦痛を経験しました。受け入れられた回答was Webでの最良の回答ですが、今のベストプラクティスは、要素の.setPointerCapture
イベントを使用することです。これにより、要素のドラッグのような動作を聞いて操作できます。 Drag
APIの狭い動作に囲まれることなく。それを行う1つの方法は次のようになります。
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)
}
明らかな贈り物は、ここのバックドアに忍び寄るカーソルハイジャックがないことです。
これを試して !わたしにはできる !
.draggable {
cursor: -webkit-grab;
cursor: grab;
}
.draggable:active {
cursor: -webkit-grabbing;
cursor: grabbing;
}
純粋なJavaScript
を使用したドラッグ可能な要素について少しだけ知っています。次のことを説明できないのは残念です。
問題は、onDragEnd
が呼び出されないため、何かを検索してこれを見つけました example ドラッグ可能な要素を使用しています。
さて、onDragStart
イベントの機能を変更すると機能しますが、ボディのクラスを変更するような別の方法でカーソルを変更する必要があると思いますonDragStart
var onDragStart = function(event) {
event.dataTransfer.setData("Text", event.target.id);
event.currentTarget.classList.add("being-dragged");
};
オールインワン
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: 500px;
background-color: silver;
}
.block {
width: 200px;
height: 50px;
background-color: pink;
}
.draggable1 {
cursor: -webkit-grab;
cursor: grab;
}
.being-dragged {
cursor: -webkit-grabbing;
cursor: grabbing;
background-color: red;
}
<div class="dropzone" ondragover="onDragOver(event);">
<div class="draggable1 block" draggable="true" ondragstart="onDragStart(event);" ondragend="onDragEnd(event);">
I'm draggable
</div>
</div>
私はしばらくの間、この解決策を見つけるために費やし、このトリックで終わりました。これは、コードを減らして適切に機能する最善の方法だと思います。
.drag{
cursor: url('../images/grab.png'), auto;
}
.drag:active {
cursor: url('../images/grabbing.png'), auto;
}