After starting the drag of a DOM element with draggable attribute , Could we stop dragging and exit from drag and drop?

517 Views Asked by At

I have to stop the drag async after the drag is started. Can I add something in drag event to cancel the drag ?

document.querySelector('#drag-elem').addEventListener('drag', function(e){
  // Stop the drag
  e.preventDefault();
})

document.querySelector('#drag-elem').addEventListener('dragstart', function(e){
  console.log('dragstart')
})
<div draggable='true' id='drag-elem'>Draggable</div>

1

There are 1 best solutions below

2
kol On BEST ANSWER

You can use a dataIsValid flag to decide if the drop is allowed in both the ondragover and ondrop event handlers. Here is an example where the data is random number between 0 and 1, which is considered valid when larger than 0.5, and the asynchronous validation takes one whole second. Try dragging the Source over the Target and wait for at least one second before releasing the left mouse button.

let dataIsValid = false;

function validateData(data) {
  dataIsValid = data.value > 0.5;
  console.log(`Data is ${dataIsValid ? "valid" : "invalid"}: ${data.value.toFixed(2)}`);
}

function onDragStart(event) {
  // Create data to be transferred
  const data = {
    value: Math.random()
  };
  event.dataTransfer.setData("text", JSON.stringify(data));
  event.target.textContent = data.value.toFixed(2);
  
  // Start asynchronous validation
  dataIsValid = false;
  setTimeout(() => validateData(data), 1000);
}

function onDragOver(event) {
  if (dataIsValid) {
    event.preventDefault();  
  }
}

function onDrop(event) {
  if (dataIsValid) {
    event.preventDefault();  
    const data = JSON.parse(event.dataTransfer.getData("text"));
    event.target.textContent = data.value.toFixed(2);
  }
}
div.circle {
  display: inline-block;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  text-align: center;
  vertical-align: middle;
  line-height: 100px;
  font-family: Arial, Helvetica, sans-serif;
}

div#source {
  background: coral;
}

div#target {
  background: lightblue;
}
<div id="source" class="circle" draggable="true" ondragstart="onDragStart(event)">Source</div>
<div id="target" class="circle" ondragover="onDragOver(event)" ondrop="onDrop(event)">Target</div>