Reputation: 121
hi.
I'm trying to find out how to hide the "drag not allowed" cursor during a drag operation.
I could be okay with changing it too, if removing isn't possible. I feel like I'm not getting something though, it sounds like an easy thing, doesn't it?
Here I've made a small fiddle for showing the issue: JSFiddle
box0.addEventListener('dragstart', dragStart);
box0.addEventListener('dragend', dragend);
box0.addEventListener('dragenter', dragEnter);
box0.addEventListener('dragover', dragOver);
container.addEventListener('dragenter', dragEnter);
container.addEventListener('dragover', dragOver);
container.addEventListener('dragend', dragend);
function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id);
setTimeout (() => {e.target.classList.add('boxh');}, 0);}
function dragend(e) {
e.target.classList.remove('boxh');
}
function dragEnter(e) {
e.preventDefault();
}
Upvotes: 12
Views: 13954
Reputation: 17
I don't know if I can answer this question (it's been more than a year), but I stumbled into this issue today, and I was surprised by how hard is to change the cursor while dragging an element using JS.
I tried to use dataTransfer
object, the dropEffect
property and the dragEvent
event, and none of these worked for me (even following MDN Web Docs).
So, for those out there who are still struggling to change the cursor while dragging, try to do this (it worked for me):
Summary Note: Simply add a CSS class with pointer-events
set to none
to the elements you don't want the "not allowed" cursor to display.
// Get the container
const file_container = document.querySelector("#file_container")
// Get the files
const files = document.querySelectorAll("[data-id='file']")
// Iterate each file
for (let file of files)
{
// Start to drag the file
file.addEventListener("dragstart", (ev)=>{
ev.target.classList.add("ds_awaiting_file")
})
// Allow drop by preventing dragover event
file_container.addEventListener("dragover", (ev)=>{ev.preventDefault()})
// Remove applied styles to the awaiting file
document.addEventListener('dragend', ()=>{
file.classList.remove("ds_awaiting_file")
});
}
/* Problem Solver (select div's children) */
[data-id=file] *
{
pointer-events: none;
}
/* General Style */
#file_container
{
display: grid;
grid-template-columns: 160px 160px 160px;
grid-template-rows: 100px;
grid-column-gap: 20px;
grid-row-gap: 20px;
}
[data-id=file]
{
border: 2px solid #1E3050;
padding: 12px 60px
}
.block
{
background-color: #1E3050;
height: 40px;
width: 40px;
}
.ds_awaiting_file
{
opacity: 0.3;
}
<div id="file_container">
<div data-id="file" draggable="true">
<div class="block"></div>
<p>File_1</p>
</div>
<div data-id="file" draggable="true">
<div class="block"></div>
<p>File_2</p>
</div>
<div data-id="file" draggable="true">
<div class="block"></div>
<p>File_3</p>
</div>
<div data-id="file" draggable="true">
<div class="block"></div>
<p>File_4</p>
</div>
</div>
This will hide the "drag not allowed" cursor during drag operation but keep in mind that (in some browsers such as Google Chrome and Opera), borders and margins will still be considered as no-allowed elements.
Upvotes: 0
Reputation: 1910
To prevent the forbidden cursor the preventDefault()
also needs to go on the target element (!!) - preferably the entire document
document.addEventListener("dragover", (event) => {
event.preventDefault();
});
Upvotes: 13
Reputation: 99
To hide the not-allowed cursor and make your drop zones valid you need to apply preventDefault on both dragOver and dragEnter.
Once you have a valid drop zone you can change the cursor with e.dataTransfer.dropEffect to either "copy", "move", "link", "none". (https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect)
Unfortunately doesn't seem like there's no-cursor option.
onDragOver={e => {
e.dataTransfer.dropEffect = "move";
e.preventDefault()
}}
onDragEnter={e => {
e.preventDefault()
}}
Upvotes: 9