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>
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>