21

I'm trying to implement HTML5's drag and drop in my app, but Firefox is always redirected to dropped image's source. I'm using e.stopPropagation(). In Chromium everything works as expected. Here's the code:

<section class="desktop">
  <img class="icon" style="left: 0px; top: 340px;" src="./computer.png" />
  <img class="icon" style="left: 0px; top: 170px;" src="./documents.png" />
  <img class="icon" style="left: 0px; top: 0px;" src="./bin.png" />
</section>
<script>
  window.clickedIcons = [];
  window.draggedIcon = {
    offset: [0, 0],
    element: null
  };

  //Drag & drop
  function dragStart(e) {
    window.draggedIcon.element = e.target;
    event.dataTransfer.effectAllowed = 'copyMove';
    event.dataTransfer.setData('text/plain', 'hey'); //hack

    const style = getComputedStyle(event.target);
    draggedIcon.element = event.target;
    draggedIcon.offset[0] =
        parseInt(style.getPropertyValue("left")) - event.clientX;
    draggedIcon.offset[1] =
        parseInt(style.getPropertyValue("top" )) - event.clientY;
  }

  function dragOver(e) {
    e.preventDefault();
    return false;
  }
       
  function drop(e) {
    draggedIcon.element.style.left =
        (event.clientX + window.draggedIcon.offset[0]) + 'px';
    draggedIcon.element.style.top =
        (event.clientY + window.draggedIcon.offset[1]) + 'px';
    draggedIcon.element.style.visibility = 'visible';
    draggedIcon.element = null;

    if (e.stopPropagation) { e.stopPropagation(); }
    return false;
  }

  const icons = document.querySelectorAll('.desktop .icon');
  for (const i of icons) {
    i.addEventListener('dragstart', dragStart, false);
    i.addEventListener('click', click, false);
  }

  document.body.addEventListener('dragover', dragOver, true);
  document.body.addEventListener('drop', drop, true);
</script>

Thanks!

m93a
  • 8,866
  • 9
  • 40
  • 58

1 Answers1

37

You need to prevent the default action:

function drop(e) {
    if(e.preventDefault) { e.preventDefault(); }
    if(e.stopPropagation) { e.stopPropagation(); }
    window.draggedIcon.element.style.left = (event.clientX + window.draggedIcon.offset[0]) + 'px';
    window.draggedIcon.element.style.top  = (event.clientY + window.draggedIcon.offset[1]) + 'px';
    window.draggedIcon.element.style.visibility = 'visible';
    window.draggedIcon.element = null;
    return false;
}
Jondlm
  • 8,764
  • 2
  • 24
  • 30
robertc
  • 74,533
  • 18
  • 193
  • 177
  • 4
    `preventDefault` does the job ! But could someone explain me why a drop would trigger a redirect on Firefox ?? – Matthieu Riegler Oct 22 '19 at 08:58
  • @MatthieuRiegler Wild guess: Dropping a file into Firefox navigates to the file, that's why the default is navigate to the URL being dropped. In my case, `drag` had called `event.dataTransfer.setData('text/plain', "css")` before and FF attempted to open the URL `"css"`. – awendt Apr 07 '21 at 07:41