0

Below is a list of draggable items, I want to eliminate the drag after effect which looks like the list item is going back to where it was dragged from, which happens whenever the mouse is released.

effect

function listItemDragged(e) {
    e.target.classList.add('dragging');
    let dropTarget =
        document.elementFromPoint(e.clientX, e.clientY) === null
            ? e.target
            : document.elementFromPoint(e.clientX, e.clientY);

    if (e.target.parentNode === dropTarget.parentNode) {
        dropTarget =
            dropTarget !== e.target.nextSibling
                ? dropTarget
                : dropTarget.nextSibling;
        e.target.parentNode.insertBefore(e.target, dropTarget);
    }
}

function listItemDropped(e) {
    e.target.classList.remove('dragging');
}

function onLoad() {
    let listItems = document.querySelectorAll('.draggable');
    Array.prototype.map.call(listItems, (option) => {
        option.ondrag = listItemDragged;
        option.ondragend = listItemDropped;
    });
}
onLoad();
 

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Roboto', sans-serif
}

body {
    background-color: #2b3035;
}

.draggable {
    display: flex;
    margin-top: 10px;
    padding: 10px 12px;
    border-radius: 5px;
    border: 1px solid #5c636a;
    margin-right: 5px;
    background-color: #212529;
    cursor: grab;
    color: #ffffff;
    touch-action: none
}

.dragging {
    cursor: grabbing;
    background: transparent;
    color: transparent;
    border: none;
}
 
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"/>

<ul class='sortable-list list-unstyled'>
<li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 1
</li>
<li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 2
</li>
<li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 3
</li>
<li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 4
</li>
</ul>
nlblack323
  • 155
  • 1
  • 10

1 Answers1

1

You can prevent the browser's default dragover action using the following code:

document.querySelector('.sortable-list').addEventListener("dragover", cancelDefault);

Here is a complete sample code demonstrating how to create a sortable list with drag and drop functionality:

function listItemDragged(e) {
  e.target.classList.add("dragging");
  let dropTarget =
    document.elementFromPoint(e.clientX, e.clientY) === null
      ? e.target
      : document.elementFromPoint(e.clientX, e.clientY);

  if (e.target.parentNode === dropTarget.parentNode) {
    dropTarget =
      dropTarget !== e.target.nextSibling ? dropTarget : dropTarget.nextSibling;
    e.target.parentNode.insertBefore(e.target, dropTarget);
  }
}

function listItemDropped(e) {
  e.target.classList.remove("dragging");
  e.preventDefault();
}

function onLoad() {
  let listItems = document.querySelectorAll(".draggable");
  Array.prototype.map.call(listItems, (option) => {
    option.ondrag = listItemDragged;
    option.ondragend = listItemDropped;
  });
  document.querySelector('.sortable-list').addEventListener("dragover", (e) => e.preventDefault());
}

onLoad();
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Roboto', sans-serif
}

body {
    background-color: #2b3035;
}

.draggable {
    display: flex;
    margin-top: 10px;
    padding: 10px 12px;
    border-radius: 5px;
    border: 1px solid #5c636a;
    margin-right: 5px;
    background-color: #212529;
    cursor: grab;
    color: #ffffff;
    touch-action: none
}

.dragging {
    cursor: grabbing;
    background: transparent;
    color: transparent;
    border: none;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" />

<ul class='sortable-list list-unstyled'>
  <li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 1
  </li>
  <li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 2
  </li>
  <li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 3
  </li>
  <li class='draggable' draggable='true'>
    Lorem ipsum dolor sit amet 4
  </li>
</ul>
Cody Chang
  • 507
  • 3
  • 7
  • any idea how to animate the reordering to look like [this](https://i.stack.imgur.com/QnlrW.gif)? – nlblack323 Apr 11 '23 at 01:35
  • You can apply an animation class before using the `insertBefore` method to achieve the desired effect." – Cody Chang Apr 11 '23 at 02:34
  • which animation class should I use in this case, to be able to control the swap delay? I tried `$(e.target.parentNode.insertBefore(e.target, beforeTarget)).animate()`, not sure if this is the proper way, it's not working anyway. – nlblack323 Apr 11 '23 at 02:39
  • @nlblack323 Based on the new information you provided, it seems that your question may require another solution. It might be a good idea to post a new question with the updated information to get more targeted answers from the community. Please let me know if you need any help or guidance with this. – Cody Chang Apr 11 '23 at 03:21
  • I asked this [question](https://stackoverflow.com/questions/75935047/how-to-make-a-draggable-list-change-place-before-mouse-release) a few days ago, dedicated for that purpose which got no answers yet. I will update it with the new changes so you can check it out. – nlblack323 Apr 11 '23 at 03:33