首先通过设置draggable="true"并监听dragstart事件实现元素拖拽,接着在dragover中阻止默认行为并计算插入位置以实现实时排序,最后通过drop和dragend完成放置与样式清理,结合getDragAfterElement方法精确确定目标位置,从而实现原生JS列表拖放排序功能。

拖放排序在现代网页开发中非常常见,比如任务管理看板、图库排序、列表重排等场景。J*aScript 提供了原生的拖放 API(Drag and Drop API),结合 HTML5 的 draggable 属性,可以轻松实现元素的拖拽与排序。下面详细介绍如何用原生 JS 实现一个简单的列表拖放排序功能。
要让一个元素可拖动,首先需要设置其 draggable="true" 属性。对于列表项(如 li 元素),可以这样写:
<li draggable="true">项目 1</li>
然后监听 dragstart 事件,用于标识拖拽开始,并通过 dataTransfer.setData() 存储被拖动元素的信息(例如 ID 或文本)。
示例代码:
document.querySelectorAll('li').forEach(item => {
item.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('text/plain', this.textContent);
this.classList.add('dragging');
});
});
为了让其他元素能接收被拖动的内容,必须阻止默认的拖放行为(浏览器默认不允许放置)。这需要监听目标容器的 dragover 和 drop 事件。
关键点:在 dragover 中调用 e.preventDefault() 才能触发 drop 事件。
同时,可通过监听 dragenter 和 dragle*e 来添加视觉反馈,比如高亮可放置区域。
ChatCut
AI视频剪辑工具
1086
查看详情
示例:
const container = document.getElementById('list-container');
<p>container.addEventLi
stener('dragover', function(e) {
e.preventDefault(); // 必须阻止默认行为才能 drop
const dragging = document.querySelector('.dragging');
const afterElement = getDragAfterElement(container, e.clientY);
if (afterElement == null) {
container.appendChild(dragging);
} else {
container.insertBefore(dragging, afterElement);
}
});</p><p>function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('li:not(.dragging)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}
在 drop 事件中,可以获取传输的数据并插入到目标位置。不过上面的例子已在 dragover 阶段完成 DOM 移动,因此 drop 只需补全逻辑即可。
建议在 dragend 事件中清理样式:
item.addEventListener('dragend', function() {
this.classList.remove('dragging');
});
此时整个列表的 DOM 结构已经按新顺序排列。如果需要获取最新排序数据(如提交到服务器),遍历当前所有 li 的内容即可:
function getCurrentOrder() {
return Array.from(document.querySelectorAll('#list-container li')).map(li => li.textContent);
}
实际项目中还需考虑以下细节:
基本上就这些。掌握 dragstart、dragover、drop 和 dragend 四个核心事件,就能构建出基础但实用的拖放排序功能。不复杂但容易忽略的是阻止默认行为和正确计算插入位置。
以上就是JS如何实现拖放排序_J*aScript拖放排序功能实现与交互逻辑教程的详细内容,更多请关注其它相关文章!
相关文章:
C++编译期如何执行复杂计算_C++模板元编程(TMP)技巧与应用
Windows 11怎么彻底关闭定位_Windows 11服务中禁用Geolocation
小红书网页版入口链接分享 小红书官网直接进
漫蛙漫画网页端入口 漫蛙2官方正版漫画站点
智慧团建扫码登录入口 智慧团建扫码登录入口官网版
快速CSGO开箱网站指南 CSGO开箱平台推荐
Excel文件在线转换快速入口 Excel在线格式转换网站
css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异
J*aScript打印功能_j*ascript输出控制
React Router v6 教程:构建认证保护的私有路由与重定向策略
如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率
HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解
Go语言中Map存储的结构体如何调用指针方法:深入解析与实践
支付宝如何管理隐私设置_支付宝隐私保护的配置技巧
深入理解J*aScript中的B样条曲线与节点向量生成
字由网在线版登录地址 字由网网页版安全入口
《噬血代码2》新预告片发布 展示游戏剧情
解决PHP集成HTML后CSS和图片路径加载问题的指南
抖音怎么赚钱_抖音创作者变现方法与途径指南
Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区
大麦的“候补”是什么意思 大麦候补购票规则【详解】
126邮箱账号注册 电脑版登录入口
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具
Golang如何优化内存分配与垃圾回收_Golang内存管理与GC优化实践
PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
抖音网页版平台入口 抖音网页版官网在线访问教程
qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决
怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】
Steam官网入口直达 Steam注册及登录步骤
一加 14R 快充无反应_一加 14R 充电优化
Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法
c++如何使用Meson构建系统_c++比CMake更快的构建工具
excel怎么提取文本中数字 excel函数提取技巧
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
Walmart退货API集成指南:PHP cURL实现与常见问题解析
小红书怎么解除第三方平台绑定_小红书多平台登录解绑方法介绍
Golang如何实现简单的Web表单_Golang表单提交与验证处理方法
抖音隐秘迷城小游戏入口_ 抖音冒险解谜小游戏秒玩
C++如何生成随机数_C++ random库使用方法与范围设置
使用PHP从URL路径中提取倒数第二个片段
夸克浏览器网页版最新地址 夸克浏览器官方入口合集
Go RPC HTTP服务正确实现与常见陷阱解析
Windows电脑怎么截图最方便_系统自带截图工具的5种神仙用法【技巧】
poki免费入口快捷访问 poki人气小游戏直接玩站点
Angular Material 垂直步进器:实现底部到顶部排序的教程
Log4j Console Appender性能瓶颈与高并发优化策略
深入理解Go语言中Map值与方法接收器的交互:为什么需要临时变量
QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网