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

JavaScript表格行拖拽:如何将行插入到表格tbody末尾?

问题描述

我写的表格行拖拽脚本里,dropHandler函数目前总是把拖拽的行插入到目标行之前,这个功能正常,但我想加个判断:当拖拽的行被放到最后一行之后时,要把它插入到表格tbody的末尾,请问怎么实现?

原代码示例

JavaScript代码

/*** 表格行拖拽功能 */
function dragstartHandler(ev) {
  sourceRow = ev.target;
  sourceTableId = sourceRow.closest("table").id;
}

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

function dropHandler(ev) {
  ev.preventDefault();
  targetRow = ev.target.closest("tr");
  targetTable = targetRow.closest("table");
  targetTableId = targetRow.closest("table").id;
  if (sourceTableId === targetTableId) {
    //console.log("正确的表格");
    targetTableBody = targetRow.closest("tbody");
    targetTableBody.insertBefore(sourceRow, targetRow);
    rebuildIndex(targetTableBody);
    //sourceRow.classList.remove("dragRow");
  } else {
    console.log("错误的表格")
  }
}

HTML代码

<table id="table2">
  <thead>
    <tr>
      <th>标题1</th>
      <th>标题2</th>
      <th>标题3</th>
      <th>标题4</th>
    </tr>
  </thead>
  <tbody id="tableBody-table2">
    <tr id="table2_row1" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>表格2数据1</td>
      <td>表格2数据2</td>
      <td>表格2数据3</td>
      <td>表格2数据4</td>
    </tr>
    <tr id="table2_row2" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>表格2数据5</td>
      <td>表格2数据6</td>
      <td>表格2数据7</td>
      <td>表格2数据8</td>
    </tr>
    <tr id="table2_row3" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>表格2数据8</td>
      <td>表格2数据9</td>
      <td>表格2数据10</td>
      <td>表格2数据11</td>
    </tr>
  </tbody>
</table>

解决方案

实现这个需求,只需两步判断拖拽位置是否在最后一行之后:

  1. 获取tbody里的最后一行元素
  2. 结合拖拽事件的位置信息,判断当前放置点是否在最后一行的下方

修改后的dropHandler函数

function dropHandler(ev) {
  ev.preventDefault();
  targetRow = ev.target.closest("tr");
  targetTable = targetRow.closest("table");
  targetTableId = targetRow.closest("table").id;
  
  if (sourceTableId === targetTableId) {
    targetTableBody = targetRow.closest("tbody");
    const lastRow = targetTableBody.lastElementChild;
    // 获取目标行的位置坐标
    const targetRect = targetRow.getBoundingClientRect();
    // 判断是否拖到最后一行的下方
    const isDroppedAfterLastRow = lastRow === targetRow && ev.clientY > targetRect.bottom;
    
    if (isDroppedAfterLastRow) {
      // 插入到tbody末尾
      targetTableBody.appendChild(sourceRow);
    } else {
      // 插入到目标行之前
      targetTableBody.insertBefore(sourceRow, targetRow);
    }
    
    rebuildIndex(targetTableBody);
    //sourceRow.classList.remove("dragRow");
  } else {
    console.log("错误的表格")
  }
}

逻辑说明

  • 用targetTableBody.lastElementChild获取tbody的最后一行
  • 通过getBoundingClientRect()拿到目标行的位置矩形,其中bottom是目标行底部的Y坐标
  • 当目标行是最后一行,且鼠标Y坐标(ev.clientY)大于目标行的bottom值时,判定为拖到了最后一行下方,此时用appendChild把行加到tbody末尾
  • 其他情况保持原有插入逻辑

扩展:支持拖拽到tbody空白区域

如果希望拖拽到最后一行下方的tbody空白区域也能触发插入末尾,给tbody添加拖拽事件:

<tbody id="tableBody-table2" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">

然后修改dropHandler补充判断:

function dropHandler(ev) {
  ev.preventDefault();
  targetRow = ev.target.closest("tr");
  targetTable = ev.target.closest("table");
  targetTableId = targetTable.id;
  
  if (sourceTableId === targetTableId) {
    targetTableBody = targetTable.querySelector("tbody");
    
    if (!targetRow) {
      // 拖拽到tbody空白区域,直接插入末尾
      targetTableBody.appendChild(sourceRow);
    } else {
      const lastRow = targetTableBody.lastElementChild;
      const targetRect = targetRow.getBoundingClientRect();
      const isDroppedAfterLastRow = lastRow === targetRow && ev.clientY > targetRect.bottom;
      
      if (isDroppedAfterLastRow) {
        targetTableBody.appendChild(sourceRow);
      } else {
        targetTableBody.insertBefore(sourceRow, targetRow);
      }
    }
    
    rebuildIndex(targetTableBody);
    //sourceRow.classList.remove("dragRow");
  } else {
    console.log("错误的表格")
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 13:05:26