1

As a continuation to my other question, I tried another approach to simulate drag and drop functionality using mouse events. First, here's a list of draggable elements that can be reordered on drag and drop:

function listItemDragged(e) {
    e.target.classList.add("dragging");
    if (e.clientX !== undefined) {
        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();
}

// I added the below to simulate the drag and drop sequence:

function createMouseEvent(type, element) {
    let coordinates = element.getBoundingClientRect();
    let e = new Event(type, {
        "bubbles": true, "cancelable": false, clientX: coordinates.left,
        clientY: coordinates.top
    })
    element.dispatchEvent(e)
}

function dragAndDrop() {
    let elements = document.querySelectorAll('.draggable')
    let [sourceElement, targetElement] = elements
    for (let eventType of ['mousedown', 'dragstart', 'drag']) {
        createMouseEvent(eventType, sourceElement)
    }
    for (let eventType of ['dragenter', 'dragover']) {
        createMouseEvent(eventType, targetElement)
    }
    for (let eventType of ['drop', 'dragend', 'mouseup']) {
        createMouseEvent(eventType, sourceElement)
    }
}

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

    // I added this
    dragAndDrop();

}

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' title="Drag and drop to reorder">
        Lorem ipsum dolor sit amet 1
    </li>
    <li class='draggable' draggable='true' title="Drag and drop to reorder">
        Lorem ipsum dolor sit amet 2
    </li>
    <li class='draggable' draggable='true' title="Drag and drop to reorder">
        Lorem ipsum dolor sit amet 3
    </li>
    <li class='draggable' draggable='true' title="Drag and drop to reorder">
        Lorem ipsum dolor sit amet 4
    </li>
</ul>

Note: If things are working as expected, the first and second elements should be swapped. The swapping functionality works and this can be verified by manually dragging and dropping any of the draggable elements.

nlblack323
  • 155
  • 1
  • 10

0 Answers0