实现列表拖拽排序功能,可新增,可删除,拖住排序,draggable,dragstart,dragend,dragover,利用好这几个事件,完美实现拖拽功能

你好呀,我是爱编程的Sherry,很高兴在这里遇见你!我是一名拥有十多年开发经验的前端工程师。这一路走来,面对困难时也曾感到迷茫,凭借不懈的努力和坚持,重新找到了前进的方向。我的人生格言是——认准方向,坚持不懈,你终将迎来辉煌!欢迎关注我,我将在这里分享工作中积累的经验和心得,希望我的分享能够给你带来帮助。

文章目录

      • 前言
      • 效果展示
      • 功能说明
        • 新增:
        • 删除:
        • 拖拽排序:
        • 关键点:
      • 代码实现
        • html(结构)
        • css(样式)
        • javascript(行为)
      • 总结

前言

有这么一个需求,产品要求实现一个列表拖拽排序功能,鼠标点击元素,按住移动,可将元素拖走,松开移动到新的位置,以完成拖拽排序。

效果展示

实现列表拖拽排序功能,可新增,可删除,拖住排序,draggable,dragstart,dragend,dragover,利用好这几个事件,完美实现拖拽功能_第1张图片

功能说明

新增:

点击“新增项”按钮,向列表中添加新的可拖拽的 li 项。

删除:

每个 li 项都有一个删除按钮,点击删除按钮可移除该项。

拖拽排序:

可以按住列表项拖动,松手时调整顺序。

关键点:

通过 draggable=“true” 启用列表项的拖拽功能。
dragstart 和 dragend 事件用于处理拖动过程中视觉反馈的变化。
dragover 事件用于实时检测鼠标位置并决定插入的位置。
新增和删除功能通过 DOM 操作动态处理列表项的变化。
这样就能实现一个具备基本排序、新增、删除功能的拖拽列表。

代码实现

html(结构)
<h2>拖拽排序列表h2>
<button id="addItem">新增项button>
<ul id="sortableList">
    <li draggable="true">Item 1 <button class="deleteBtn">删除button>li>
    <li draggable="true">Item 2 <button class="deleteBtn">删除button>li>
    <li draggable="true">Item 3 <button class="deleteBtn">删除button>li>
ul>
css(样式)
/* 简化并增强样式 */
ul {
    list-style-type: none;
    padding: 0;
}

li {
    margin: 10px;
    padding: 15px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    cursor: grab;
    display: flex;
    justify-content: space-between;
}

li.dragging {
    opacity: 0.5;
    background-color: #c0c0c0;
}

button.deleteBtn {
    background-color: red;
    color: white;
    border: none;
    cursor: pointer;
}

button.deleteBtn:hover {
    background-color: darkred;
}
javascript(行为)
const sortableList = document.getElementById("sortableList");
const addItemBtn = document.getElementById("addItem");

addItemBtn.addEventListener("click", () => {
    const newItem = document.createElement("li");
    newItem.setAttribute("draggable", "true");
    newItem.innerHTML = `Item ${sortableList.children.length + 1} `;
    sortableList.appendChild(newItem);
    addDragAndDeleteListeners(newItem);
});

function addDragAndDeleteListeners(item) {
    
    item.addEventListener("dragstart", () => {
        item.classList.add("dragging");
    });

    item.addEventListener("dragend", () => {
        item.classList.remove("dragging");
    });

    const deleteBtn = item.querySelector(".deleteBtn");
    deleteBtn.addEventListener("click", () => {
        item.remove();
    });
}

sortableList.addEventListener("dragover", (e) => {
    e.preventDefault();
    const draggingItem = document.querySelector(".dragging");
    const closestItem = getDragAfterElement(sortableList, e.clientY);
    if (closestItem === null) {
        sortableList.appendChild(draggingItem);
    } else {
        sortableList.insertBefore(draggingItem, closestItem);
    }
});

function getDragAfterElement(container, y) {
    const listItems = [...container.querySelectorAll("li:not(.dragging)")];

    return listItems.reduce((closest, child) => {
        const box = child.getBoundingClientRect();
        const offset = y - box.top - box.height / 2;
        if (offset < 0 && offset > closest.offset) {
            return { offset: offset, element: child };
        } else {
            return closest;
        }
    }, { offset: Number.NEGATIVE_INFINITY }).element;
}

document.querySelectorAll("#sortableList li").forEach(addDragAndDeleteListeners);

总结

通过上述代码实现了拖拽排序功能的核心特性,首先html创建布局,然后css设计样式,确保良好的视觉反馈,增强用户体验;最后利用html5的draggable属性和相关事件(如dragstart、dragover和dragend)实现元素的拖拽功能。

看十遍不然练一遍,快快动手练起来吧!

你可能感兴趣的:(javascript,javascript,前端)