一、推荐教程
二、demo 体验
2.1、菜鸟教程demo
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>基础教程(cainiaojc.com)</title>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<p>拖动 nhooo.COM 图片到矩形框中:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="/static/images/logo-n.png" draggable="true" ondragstart="drag(event)" width="336" height="69">
</body>
</html>

2.2、AI demo
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 拖放API与表格输出</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.draggable-items {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.draggable-item {
padding: 10px;
background-color: #4CAF50;
color: white;
border-radius: 4px;
cursor: move;
user-select: none;
}
.table-container {
margin-top: 20px;
}
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.drop-zone {
min-height: 50px;
border: 2px dashed #ccc;
border-radius: 4px;
padding: 10px;
}
.drop-zone.highlight {
border-color: #4CAF50;
background-color: #f0fff0;
}
</style>
</head>
<body>
<h1>HTML5 拖放API与表格输出</h1>
<div class="draggable-items">
<div class="draggable-item" draggable="true" data-id="1">项目 1</div>
<div class="draggable-item" draggable="true" data-id="2">项目 2</div>
<div class="draggable-item" draggable="true" data-id="3">项目 3</div>
<div class="draggable-item" draggable="true" data-id="4">项目 4</div>
</div>
<div class="table-container">
<h2>拖放结果表格</h2>
<table id="resultTable">
<thead>
<tr>
<th>ID</th>
<th>项目名称</th>
<th>拖放时间</th>
</tr>
</thead>
<tbody id="tableBody">
<!-- 拖放的项目将在这里显示 -->
</tbody>
</table>
</div>
<script>
// 获取DOM元素
const draggableItems = document.querySelectorAll('.draggable-item');
const tableBody = document.getElementById('tableBody');
// 为每个可拖动元素添加事件监听器
draggableItems.forEach(item => {
item.addEventListener('dragstart', handleDragStart);
});
// 拖放区域(整个文档)
document.addEventListener('dragover', handleDragOver);
document.addEventListener('drop', handleDrop);
// 拖放开始处理函数
function handleDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.textContent);
e.dataTransfer.setData('application/json', JSON.stringify({
id: e.target.dataset.id,
text: e.target.textContent
}));
e.target.style.opacity = '0.4';
}
// 拖放经过处理函数
function handleDragOver(e) {
e.preventDefault(); // 允许放置
e.dataTransfer.dropEffect = 'move';
}
// 拖放处理函数
function handleDrop(e) {
e.preventDefault();
// 获取拖放的数据
const data = JSON.parse(e.dataTransfer.getData('application/json'));
// 创建新的表格行
const newRow = document.createElement('tr');
// 创建ID单元格
const idCell = document.createElement('td');
idCell.textContent = data.id;
// 创建项目名称单元格
const nameCell = document.createElement('td');
nameCell.textContent = data.text;
// 创建时间单元格
const timeCell = document.createElement('td');
timeCell.textContent = new Date().toLocaleString();
// 将单元格添加到行
newRow.appendChild(idCell);
newRow.appendChild(nameCell);
newRow.appendChild(timeCell);
// 将行添加到表格
tableBody.appendChild(newRow);
// 重置拖动元素的样式
draggableItems.forEach(item => {
if (item.textContent === data.text) {
item.style.opacity = '1';
}
});
}
</script>
</body>
</html>

三、拖放事件(Drag Events)
序号 | 事件名称 | 触发时机 | 关键操作 |
---|---|---|---|
1 | dragstart |
用户开始拖动元素时触发 | 设置拖动数据:event.dataTransfer.setData() |
2 | drag |
拖动过程中持续触发 | 通常无需处理,可用于实时反馈(如修改样式) |
3 | dragenter |
被拖元素进入放置目标时触发 | 常用于高亮放置区域(需preventDefault() ) |
4 | dragover |
被拖元素在放置目标上方移动时触发 | 必须调用 event.preventDefault() 以允许放置 |
5 | dragleave |
被拖元素离开放置目标时触发 | 移除高亮样式 |
6 | drop |
用户释放被拖元素到放置目标时触发 | 获取数据:event.dataTransfer.getData() ,更新DOM(如表格内容) |
7 | dragend |
拖动操作结束时触发 | 清理状态(如恢复样式) |
四、DataTransfer 对象方法
序号 | 方法/属性 | 作用 |
---|---|---|
1 | setData(format, data) |
存储拖动数据(如 text/plain , application/json ) |
2 | getData(format) |
获取拖动数据(需与setData 的format 匹配) |
3 | effectAllowed |
设置允许的拖动效果(copy /move /link /none ) |
4 | dropEffect |
指定放置时的视觉效果(需与effectAllowed 匹配) |
5 | files |
获取拖动的文件列表(用于文件上传场景) |
6 | setDragImage(image, x, y) |
自定义拖动时的预览图像 |
五、表格操作相关API
序号 | API | 用途 |
---|---|---|
1 | document.createElement() |
动态创建表格行(<tr> )或单元格(<td> ) |
2 | element.appendChild() |
将新行添加到表格的<tbody> 中 |
3 | element.insertBefore() |
在指定位置插入行 |
4 | table.insertRow() |
快速创建新行(需指定索引) |
5 | row.insertCell() |
在行中插入单元格 |
6 | element.textContent |
设置单元格文本内容 |
7 | element.innerHTML |
设置单元格HTML内容(支持复杂结构) |
六、插件推荐
6.1、Vue.Draggable(Vue专用)
特点:基于SortableJS封装,提供Vue组件式API,支持v-model双向绑定。
适用场景:Vue项目中的列表管理(如电商后台商品排序)。
核心方法:
<draggable v-model="items" @end="onDragEnd">
<div v-for="item in items">{{ item.name }}</div>
</draggable>
6.2、GridStack(网格布局专用)
特点:支持响应式网格、动态调整大小,内置保存/恢复布局功能。
适用场景:仪表盘设计、数据可视化看板。
配置示例:
$('.grid-stack').gridstack({
width: 12,
float: true,
cellHeight: 60
});