You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现Table内Div跨TD拖拽,支持已移入TD的Div再次拖拽

问题描述

我希望将表格内的Div拖拽到不同的TD中,同时保持源Div中的元素可见(该功能已实现)。目前我需要让所有TD内的Div都具备可拖拽能力,恳请各位提供帮助。

操作示意图

当前代码

JavaScript

function allowDrop(ev) {
  ev.preventDefault();
}

function drag(ev) {
  ev.dataTransfer.setData("text", ev.target.id);
  ev.dataTransfer.effectAllowed = "copy";
}

function drop(ev) {
  ev.preventDefault();
  var data = ev.dataTransfer.getData("text");
  var copyimg = document.createElement("div");
  var parent = document.createElement("conteudo");
  var original = document.getElementById(data);
  copyimg.id = original.id;
  copyimg.innerHTML = original.innerHTML;
  copyimg.style.position = "absolute";
  copyimg.draggable = "true";
  ev.target.appendChild(copyimg);
}

CSS

table, th, td {
  border:1px solid black;
  height: 40px;
  width: 80px;
}

HTML

<div style="width:100%">
  <table style="width:80%;float:left">
    <tr>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
    </tr>
    <tr>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
    </tr>
    <tr>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
      <td ondrop="drop(event)" ondragover="allowDrop(event)"></td>
    </tr>
  </table>
  <div style="background:yellow ;width:15%;float:left;margin-left:10px">
    <div class="droppable" draggable="true" ondragstart="drag(event)" id="drag1">aaa</div>
    <div class="droppable" draggable="true" ondragstart="drag(event)" id="drag2">bbb</div>
    <div class="droppable" draggable="true" ondragstart="drag(event)" id="drag3">ccc</div>
  </div>
</div>
解决方案

要让TD内生成的Div也具备可拖拽能力,需要解决ID冲突和事件绑定两个核心问题,修改后的代码如下:

优化后的JavaScript

function allowDrop(ev) {
  ev.preventDefault();
}

function drag(ev) {
  // 传递元素完整HTML结构,避免ID冲突问题
  ev.dataTransfer.setData("text/html", ev.target.outerHTML);
  ev.dataTransfer.effectAllowed = "copy";
}

function drop(ev) {
  ev.preventDefault();
  var html = ev.dataTransfer.getData("text/html");
  // 解析HTML字符串生成新元素
  var tempContainer = document.createElement("div");
  tempContainer.innerHTML = html;
  var copyDiv = tempContainer.firstElementChild;

  // 移除重复ID,避免DOM选择异常
  copyDiv.removeAttribute("id");
  // 绑定拖拽事件,确保新元素可拖拽
  copyDiv.setAttribute("ondragstart", "drag(event)");
  // 修正布局问题,改为相对定位
  copyDiv.style.position = "relative";

  ev.target.appendChild(copyDiv);
}

修改说明

  1. 解决ID冲突:不再传递元素ID,改为传递完整HTML结构,生成新元素时移除原始ID,避免同一页面出现重复ID导致的DOM操作异常。
  2. 绑定拖拽事件:给新创建的Div显式添加ondragstart属性,确保所有TD内的Div都能触发拖拽功能。
  3. 优化布局:将position: absolute改为relative,避免Div脱离TD布局流,保证元素在TD内正常显示。
  4. 通用拖拽支持:无论初始侧边栏的Div还是TD内生成的Div,都能触发拖拽逻辑,实现跨TD的拖拽复制。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:40:39