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>