Dlofud
Dlofud

Reputation: 121

How can I hide (or change) the drag not allowed cursor during a dragging?

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

Answers (3)

Fito
Fito

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

Robb Hoff
Robb Hoff

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

lilpostloo
lilpostloo

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

Related Questions