学习JavaScript开发Kanban看板:拖拽功能实现求助及代码优化
解决Kanban看板跨容器拖拽问题及代码优化建议
下面是修复拖拽功能后的完整代码,同时附带代码优化的细节说明:
修改后的完整代码
JavaScript
const button = document.getElementById("dataEntryButton"); const boxDataContainer = document.getElementById("boxDataContainer"); const boxDataContainer1 = document.getElementById("boxDataContainer1"); const containerDataEntry = document.getElementById("containerDataEntry"); const createTable = (data) => { const div = document.createElement("div"); const text = document.createElement("h1"); const deleteTable = document.createElement("button"); // 开启元素拖拽功能 div.draggable = true; div.classList.add("draggable-item"); text.innerText = data; deleteTable.innerText = "Delete Table"; // 修复删除逻辑:直接移除当前元素,不再绑定固定容器 deleteTable.addEventListener("click", () => { div.remove(); }); // 拖拽开始:存储元素ID,添加视觉反馈 div.addEventListener("dragstart", (e) => { e.dataTransfer.setData("text/plain", div.id); div.style.opacity = "0.5"; }); // 拖拽结束:恢复元素状态 div.addEventListener("dragend", () => { div.style.opacity = "1"; }); // 给每个拖拽元素分配唯一ID div.id = `draggable-${Date.now()}`; div.appendChild(text); div.appendChild(deleteTable); return div; }; // 统一设置容器的拖拽接收逻辑,避免重复代码 const setupDropArea = (container) => { // 允许放置必须阻止默认行为 container.addEventListener("dragover", (e) => { e.preventDefault(); container.classList.add("drag-over"); }); // 拖拽离开容器时移除高亮 container.addEventListener("dragleave", () => { container.classList.remove("drag-over"); }); // 处理放置动作 container.addEventListener("drop", (e) => { e.preventDefault(); container.classList.remove("drag-over"); const draggedId = e.dataTransfer.getData("text/plain"); const draggedElement = document.getElementById(draggedId); if (draggedElement) { container.appendChild(draggedElement); } }); }; // 初始化两个拖拽容器 setupDropArea(boxDataContainer); setupDropArea(boxDataContainer1); button.addEventListener("click", () => { const data = containerDataEntry.value.trim(); if (!data) return; // 空内容不创建元素 const table = createTable(data); boxDataContainer.appendChild(table); containerDataEntry.value = ""; // 清空输入框 });
CSS
#boxDataEntry { margin: 10px; } .dropArea { border: 1px solid black; min-height: 100px; /* 替换固定高度,避免元素溢出容器 */ margin: 10px; padding: 10px; transition: background-color 0.2s ease; } /* 拖拽悬停时的容器高亮样式 */ .dropArea.drag-over { background-color: #f5f5f5; border-color: #888; } .draggable-item { background-color: #fff; border: 1px solid #eee; padding: 8px; margin: 8px 0; cursor: grab; } .draggable-item:active { cursor: grabbing; } .draggable-item h1 { font-size: 16px; margin: 0 0 8px 0; } .draggable-item button { padding: 4px 8px; border: none; background-color: #ff4444; color: white; cursor: pointer; border-radius: 4px; }
HTML
<div id="boxDataEntry"> <textarea id="containerDataEntry" cols="30" rows="10"></textarea> <button id="dataEntryButton">Enter</button> </div> <div id="boxDataContainer" class="dropArea"></div> <div id="boxDataContainer1" class="dropArea"></div>
核心修改说明
拖拽功能实现
- 给每个创建的元素添加
draggable="true",并通过dragstart事件存储元素唯一ID,方便放置时定位元素。 - 给两个容器统一绑定
dragover、dragleave、drop事件:dragover阻止默认行为以允许放置,drop事件中取出拖拽元素并添加到当前容器。 - 添加拖拽过程中的视觉反馈:元素拖拽时半透明,容器被悬停时变色。
- 给每个创建的元素添加
代码优化点
- 修复删除按钮逻辑:原代码只能删除第一个容器内的元素,现在改为直接移除当前元素,适配跨容器拖拽后的删除需求。
- 添加输入校验:点击按钮时先判断输入内容是否为空,避免创建无效元素,同时清空输入框提升操作体验。
- 复用拖拽逻辑:用
setupDropArea函数统一处理两个容器的拖拽事件,减少重复代码。 - 样式优化:容器改为
min-height避免元素溢出,给拖拽元素和删除按钮添加样式,提升视觉体验。 - 移除无效代码:删除原代码中无意义的
makeDraggable变量。
内容的提问来源于stack exchange,提问作者patata
相关产品推荐
相关产品推荐

