js 原生拖拽排序功能 简单实现

拖拽排序功能还是挺常见的, 涉及到的api 还是挺多的,这里笔记记录一下以免忘记找不到了!
老规矩先上效果图

html部分

html 复制代码
 <div class="list-box">
        <div draggable="true" class="item">1</div>
        <div draggable="true" class="item">2</div>
        <div draggable="true" class="item">3</div>
        <div draggable="true" class="item">4</div>
        <div draggable="true" class="item">5</div>
        <div draggable="true" class="item">6</div>
    </div>

js 部分

js 复制代码
 <script>
        const list = document.querySelector('.list-box');
        let sourceNode;
        // 开始 拖拽
        list.ondragstart = (e) => {
            setTimeout(() => {
                e.target.classList.add('moving');
            }, 0)
            sourceNode = e.target
        };
        // 禁止元素在列表上方释放
        list.ondragover = (e) => {
            e.preventDefault();
        };
        // 拖拽进入
        list.ondragenter = (e) => {
            // 阻止默认行为
            e.preventDefault();
            // 排除 拖拽到外面 和 拖拽原本的位置
            if (e.target == list || e.target == sourceNode) return;
            const chidList = [...list.children]
            // 获取拖拽元素的下标
            const sourceIndex = chidList.indexOf(sourceNode);
            // 进入的元素下标
            const targetIndex = chidList.indexOf(e.target);
            if (sourceIndex < targetIndex) {
                // 将拖拽元素放在当前元素下方
                list.insertBefore(sourceNode, e.target.nextElementSibling)
            } else {
                // 将拖拽元素放在当前元素上方
                list.insertBefore(sourceNode, e.target)
            }
        };
        // 拖动结束移除默认样式
        list.ondragend = () => {
            sourceNode.classList.remove('moving')
        } 
    </script>

css 部分 这个图拽动画 要是相弄得好看还是有难度的 ,我就随便写了点样式

css 复制代码
<style>
        .list-box {
            list-style: none;
            width: 500px;
            margin: 0 auto;
            /* line-height: 30px; */
        }

        .item {
            background: aquamarine;
            height: 40px;
            line-height: 40px;
            border-radius: 4px;
            margin-bottom: 10px;
            user-select: none;
            transition: background-color 0.3s ease;
        }

        .item.moving {
            background: transparent;
            color: transparent;
            border: 1px dashed #ccc;
            transition: none;
        }
    </style>
相关推荐
海天胜景15 分钟前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘36 分钟前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾40 分钟前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉1 小时前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
秃了也弱了。1 小时前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)1 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~2 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中2 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
然我2 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html
NanLing2 小时前
【纯前端推理】纯端侧 AI 对象检测:用浏览器就能跑的深度学习模型
前端