Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent HTML5 Drag Ghost Image Flying Back

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?

like image 742
Nicholas Haley Avatar asked Mar 10 '17 18:03

Nicholas Haley


1 Answers

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>
like image 188
Julien Grégoire Avatar answered Nov 07 '22 20:11

Julien Grégoire