You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

拖拽事件开发疑问:如何保留被拖拽元素的初始位置

解决拖拽后元素保留在初始位置的问题

嘿,我看你遇到了拖拽操作后原元素被移走的问题——这其实是因为你当前的代码里直接把元素移动到了目标容器,而不是复制它。咱们来一步步搞定这个问题:

问题根源

你在drag函数里写的document.getElementById("tareas").append(document.getElementById(data));这行代码,会把DOM节点从它原来的父元素中移除,然后添加到#tareas容器里。这就是为什么原位置的元素消失了。要让原元素留在原位,我们需要复制一个元素副本,把副本放到目标容器里。

修正后的完整实现

首先,我们要遵循标准的拖拽事件流程:dragstart(设置拖拽数据)→dragover(允许放置)→drop(处理放置逻辑),而不是把所有逻辑都堆在dragstart里。

1. JavaScript代码

// 拖拽开始时设置数据
function drag(ev) {
  ev.dataTransfer.setData("text", ev.target.id);
}

// 允许放置:必须阻止默认行为,否则drop事件不会触发
function allowDrop(ev) {
  ev.preventDefault();
}

// 处理放置逻辑:复制元素并添加到目标容器
function drop(ev) {
  ev.preventDefault();
  // 获取拖拽的元素ID
  const elementId = ev.dataTransfer.getData("text");
  const originalElement = document.getElementById(elementId);
  
  // 复制原元素:cloneNode(true)表示深复制(包含子元素和属性)
  const elementCopy = originalElement.cloneNode(true);
  
  // 给副本设置新ID(可选,但避免页面上出现重复ID)
  elementCopy.id = `${elementId}-copy-${Date.now()}`;
  
  // 将副本添加到目标容器
  document.getElementById("tareas").append(elementCopy);
}

2. 对应的HTML修改

给目标容器#tareas添加ondragoverondrop事件绑定:

<!-- 目标容器 -->
<div id="tareas" ondragover="allowDrop(event)" ondrop="drop(event)"></div>

<!-- 可拖拽元素 -->
<p id="item1" class="text-danger materias" draggable="true" ondragstart="drag(event)">Cambio aceite</p>

关键说明

  • cloneNode(true):这个方法会创建原元素的完整副本,包括所有子元素、属性和类名。如果你只需要复制元素本身(不包含子元素),可以用cloneNode(false)
  • 阻止默认行为:dragoverdrop事件里必须调用ev.preventDefault(),否则浏览器会执行默认的拖拽行为(比如打开链接),导致我们的自定义逻辑失效。
  • 副本ID:给副本设置新ID是个好习惯,避免页面上出现重复的ID,这可能会导致后续DOM操作出问题。

这样修改后,你拖拽元素时,原元素会留在初始位置,同时目标容器里会出现一个一模一样的副本,完全符合你的需求~

内容的提问来源于stack exchange,提问作者Jaime Cuellar

火山引擎 最新活动