You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模拟鼠标事件的拖拽序列未按预期工作

模拟拖拽排序功能未达预期

我在之前的拖拽排序问题基础上,尝试通过模拟鼠标事件实现列表元素的拖拽重排。手动拖拽时,第一个和第二个元素能正常交换位置,但模拟的鼠标事件序列却没达到预期效果。

以下是可拖拽重排的元素列表及实现代码:

JavaScript 代码

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();
}

// 新增代码用于模拟拖拽序列:

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());

    // 调用模拟函数
    dragAndDrop();

}

onLoad();

CSS 代码

* {
    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;
}

HTML 代码

<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>

注:功能正常时第一个与第二个元素应完成交换,手动拖拽可验证该功能有效,但模拟的鼠标事件序列未达预期效果。

内容的提问来源于stack exchange,提问作者nlblack323

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:37:50