I am building a sortable list that uses the HTML5 drag and drop. It works well, but I have a frustrating problem when it comes to the ghost image. The ghost image always wants to fly back to the location that it came from. The result is that if a list item change positions, the ghost image will fly back to the wrong list item.
Ideally, the ghost image should just not show at all after the onDragEnd
event. I've tried setting the image to an empty image on dragEnd with
handleDragEnd(e) {
e.dataTransfer.setDragImage(new Image(0, 0), 0, 0);
...
but I think that you can only use setDragImage
in onDragStart
.
Is there a way to hide the ghost image onDragEnd
, or at the very least get it to fly back to the correct location?
The revert effect is the default behavior on Safari, but you can control this default behavior in the HTML that you control. You only need to add a dragover event on the zone on which you want to prevent this revert effect and call e.preventDefault(). Only limitation: you won't be able to control when user drags the element out of the browser or the frame that you control.
But something like this gets rid of the problem you're describing:
var draggedId;
var img = new Image();
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAO0lEQVR42u3OMQ0AMAgAsGFiCvCvDQeggoSjVdD4lf0OC0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBwR0DX1VWkeseHpAAAAAASUVORK5CYII=";
document.getElementById('a').ondragstart = dragstart_handler;
document.getElementById('b').ondragstart = dragstart_handler;
document.ondragover = (e) => {
if (draggedId === "a") {
e.preventDefault();
}
}
function dragstart_handler(e) {
draggedId = e.target.id;
e.dataTransfer.setDragImage(img, 0, 0)
}
div {
cursor: pointer;
}
div:hover {
color: blue;
}
<div id=a draggable=true>
This element won't revert on dragend.
</div>
<div id=b draggable=true>
This one will revert.
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With