拖拽元素放置错误时恢复原位置的HTML+JS技术问题
拖拽元素的归位与隐藏需求实现
我基于一段现有代码做了修改,需要实现以下两个核心需求:
- 拖拽圆形按钮时,元素从初始位置隐藏,明确提示正在移动
- 若将元素放置到错误位置,自动恢复至初始位置
现有HTML代码
<div id="bracelet"> <div id="div1-1" ondrop="drop(event)" ondragover="allowDrop(event)"></div> <div id="div1-2" ondrop="drop(event)" ondragover="allowDrop(event)"></div> <div id="div1-3" ondrop="drop(event)" ondragover="allowDrop(event)"></div> </div> <br/><br/><br/><br/><br/> <div id="div2" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag1" src="http://upload.wikimedia.org/wikipedia/commons/4/4f/Button-Red.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div3" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag2" src="http://upload.wikimedia.org/wikipedia/commons/a/a8/Button-Blue.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div4" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag3" src="http://upload.wikimedia.org/wikipedia/commons/c/ca/Button-Lightblue.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div5" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag4" src="http://upload.wikimedia.org/wikipedia/commons/b/ba/Button-Purple.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div6" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag5" src="http://upload.wikimedia.org/wikipedia/commons/6/68/Button-Orange.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div7" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag6" src="http://upload.wikimedia.org/wikipedia/commons/d/dc/Button-Green.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div8" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag7" src="http://upload.wikimedia.org/wikipedia/commons/4/4f/Button-Red.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div9" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag8" src="http://upload.wikimedia.org/wikipedia/commons/a/a8/Button-Blue.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div10" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag9" src="http://upload.wikimedia.org/wikipedia/commons/c/ca/Button-Lightblue.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div11" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag10" src="http://upload.wikimedia.org/wikipedia/commons/b/ba/Button-Purple.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div12" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag11" src="http://upload.wikimedia.org/wikipedia/commons/6/68/Button-Orange.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div> <div id="div13" class="drop" ondrop="drop(event)" ondragover="allowDrop(event)"> <img id="drag12" src="http://upload.wikimedia.org/wikipedia/commons/d/dc/Button-Green.svg" ondragend="dragEnd(event)" draggable="true" ondragstart="drag(event)" width="50" height="50"> </div>
现有JS代码
function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { var el = ev.target; var parent = el.getAttribute("data-parent"); if(!parent){ el.setAttribute("data-parent", el.parentNode.id); } ev.dataTransfer.setData("Text", el.id); setTimeout(() => { ev.target.classList.add('hide'); // 拖拽时隐藏初始位置元素,需在CSS中定义.hide类 }, 0); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); ev.target.classList.remove('drag-over'); const id = ev.dataTransfer.getData('text/plain'); const draggable = document.getElementById(id); ev.target.appendChild(draggable); draggable.classList.remove('hide'); } function dragEnd(ev){ if(ev.dataTransfer.dropEffect == "none"){ var parent = document.getElementById(ev.target.getAttribute("data-parent")); parent.appendChild(ev.target); } }
修正后的完整实现
1. 添加必要CSS
.hide { display: none; } /* 可选:给放置区域添加样式,方便识别 */ #bracelet div { width: 60px; height: 60px; border: 2px dashed #ccc; display: inline-block; margin: 0 10px; } .drop { display: inline-block; margin: 0 5px; }
2. 修正JS逻辑
function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { const el = ev.target; // 存储初始父容器ID,仅第一次拖拽时设置 if (!el.getAttribute("data-parent")) { el.setAttribute("data-parent", el.parentNode.id); } ev.dataTransfer.setData("Text", el.id); // 延迟隐藏,确保拖拽事件触发后隐藏初始位置元素 setTimeout(() => { el.classList.add('hide'); }, 0); } function drop(ev) { ev.preventDefault(); const id = ev.dataTransfer.getData("Text"); const draggable = document.getElementById(id); const target = ev.target; // 定义正确的放置区域:仅#bracelet下的容器允许放置 const isValidZone = target.closest('#bracelet') !== null; if (isValidZone) { // 放置到正确位置,显示元素 target.appendChild(draggable); draggable.classList.remove('hide'); } else { // 错误位置,先显示元素,等待dragEnd归位 draggable.classList.remove('hide'); } } function dragEnd(ev) { const draggable = ev.target; // 未成功放置(dropEffect为none)时,恢复到初始位置 if (ev.dataTransfer.dropEffect === "none") { const originalParentId = draggable.getAttribute("data-parent"); const originalParent = document.getElementById(originalParentId); originalParent.appendChild(draggable); draggable.classList.remove('hide'); } }
3. HTML注意事项
- 原代码中
#bracelet下的三个div使用了重复的id="div1",已修正为唯一ID(div1-1、div1-2、div1-3),符合HTML规范。
内容的提问来源于stack exchange,提问作者alfredo49
相关产品推荐
相关产品推荐

