复刻Sortieren游戏时的Drag&Drop功能问题求助
问题分析与修复方案
一、拖拽功能失效的核心问题
- 函数名大小写不匹配:HTML中
ondragover绑定的是allowdrop(event),但JS里定义的函数是allowDrop(驼峰命名),大小写错误导致事件无法触发。 - 拖拽元素缺少唯一ID:
drag函数依赖元素ID传递数据,但大部分.sort1元素没有设置唯一ID,导致拖拽时无法定位目标元素。
二、无法按顺序拖拽的问题
当前drop函数仅将元素追加到容器末尾,没有处理插入位置的逻辑,无法实现自定义排序。需要修改drop函数,根据拖拽位置将元素插入到容器内的对应位置。
三、修正后的完整代码
1. JavaScript 代码
function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { // 确保传递元素的ID,若元素无ID则生成临时唯一ID const elementId = ev.target.id || `drag-${Date.now()}-${Math.random().toString(36).slice(2,9)}`; ev.target.id = elementId; ev.dataTransfer.setData("text", elementId); } function drop(ev) { ev.preventDefault(); const data = ev.dataTransfer.getData("text"); const draggedElement = document.getElementById(data); const dropTarget = ev.target; // 判断是否是dropper或Begriffe容器,或者容器内的子元素 const validContainer = dropTarget.id === "dropper" || dropTarget.id === "Begriffe" || dropTarget.closest("#dropper, #Begriffe"); if (!validContainer) return; const container = dropTarget.id === "dropper" || dropTarget.id === "Begriffe" ? dropTarget : dropTarget.closest("#dropper, #Begriffe"); // 处理插入位置:如果拖拽到容器内的元素上方,插入到该元素前面 if (dropTarget.classList.contains("sort1")) { container.insertBefore(draggedElement, dropTarget); } else { // 否则追加到容器末尾 container.appendChild(draggedElement); } }
2. HTML 代码
<div id="sortieren"> <div id="higher" draggable="false">Higher</div> <div id="dropper" ondrop="drop(event)" ondragover="allowDrop(event)">Dropper <div class="sort1" draggable="true" ondragstart="drag(event)" ondrop="return false" ondragover="return false" id="drag1">Moonlanding</div> </div> <div id="lower" draggable="false">Lower</div> </div> <div id="Begriffe" ondrop="drop(event)" ondragover="allowDrop(event)"> <div class="sort1" draggable="true" ondragstart="drag(event)" ondrop="return false" ondragover="return false" id="drag2">Moonlanding</div> <div class="sort1" draggable="true" ondragstart="drag(event)" ondrop="return false" ondragover="return false" id="drag3">Moonlanding 23</div> <div class="sort1" draggable="true" ondragstart="drag(event)" ondrop="return false" ondragover="return false" id="drag4">Moonlanding 44</div> </div>
3. CSS 代码(保留原代码即可)
#sortieren { float: left; width: 20%; height: 1000px; margin: 10px; padding: 10px; border: 1px solid black; } #higher { float: center; width: 88%; height: 15px; margin: 10px; padding: 10px; border: 1px solid black; text-align: center; } #dropper { float: center; width: 88%; height: 500px; margin: 20px; border: 1px solid black; } #lower { float: center; width: 88%; height: 15px; margin: 10px; padding: 10px; border: 1px solid black; text-align: center; } #Begriffe { float: right; width: 75%; height: 1000px; border: 1px solid black; margin: 10px; padding: 10px; justify-content: center; } .sort1 { background-image: linear-gradient(92.88deg, #455EB5 9.16%, #5643CC 43.89%, #673FD7 64.72%); border-radius: 16px; border-style: none; box-sizing: border-box; color: #FFFFFF; cursor: pointer; flex-shrink: 0; font-family: "Inter UI", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; font-size: 16px; font-weight: 500; height: 4rem; padding: 0 1.6rem; text-align: center; text-shadow: rgba(0, 0, 0, 0.25) 0 3px 8px; transition: all .5s; user-select: none; -webkit-user-select: none; touch-action: manipulation; margin: 50px } .sort1:hover { box-shadow: rgba(80, 63, 205, 0.5) 0 1px 30px; transition-duration: .1s; } @media (min-width: 768px) { .sort1 { padding: 0 2.6rem; } }
四、关键修改说明
- 修复函数名大小写:将HTML中
ondragover="allowdrop(event)"改为ondragover="allowDrop(event)",与JS函数名匹配。 - 确保拖拽元素有ID:给所有
.sort1元素添加唯一ID,同时在drag函数中增加兜底逻辑,自动生成临时ID避免遗漏。 - 实现自定义排序:修改
drop函数,判断拖拽目标是容器还是容器内的元素,若拖拽到元素上方则插入到该元素前,否则追加到末尾,支持自由调整顺序。
内容的提问来源于stack exchange,提问作者Evail
相关产品推荐
相关产品推荐

