表格拖拽原生实现

dataTransfer对象

dataStart 时 setData,drop 时 getData

  1. 数据格式必须一致
    getData(format)format 参数必须与 setData(format, data) 中设置的格式完全匹配 (如 "drag_index")。

    • ❌ 错误:setData("text/plain", "123")getData("drag_index") 会返回空字符串。

    • ✅ 正确:setData("drag_index", "123")getData("drag_index") 返回 "123"

  2. 数据类型限制
    dataTransfer 只能存储字符串 。如需传递对象,需先序列化(如 JSON.stringify)。

  3. 浏览器安全限制

    • 拖放数据默认仅在同一页面或同源页面间共享。

    • 跨域拖放可能无法读取数据(需特殊处理)。

  4. 注意事项:

    lua 复制代码
    方法/属性作用setData(format, data)在 dragstart 事件中设置要传递的数据(格式如 "text/plain")。getData(format)在 drop 事件中获取数据(如 "drag_index")。files获取拖拽的文件列表(用于文件拖放)。effectAllowed设置允许的拖拽效果(如 "copy", "move")。

表格拖拽方法

  1. drag事件

ini 复制代码
 <div class="dropzone">
   <div id="draggable" draggable="true">这个 div 可以拖动</div>
 </div>
 <div class="dropzone" id="droptarget"></div>
 
 拖动事件,draggable="true" 是可拖动
  1. dragStart

    复制代码
    开始拖动
  2. dragend

    javascript 复制代码
    拖放操作结束时触发(释放鼠标/单击 escape 键)
  3. dragEnter

    复制代码
    进入拖动目标放置区域
  4. dragLeave

    复制代码
    离开拖动目标放置区域
  5. drop

    sql 复制代码
    drop 事件在元素或文本选择被放置到有效的放置目标上时触发

表格实例

xml 复制代码
<!DOCTYPE html><html><head><meta charset="utf-8"><title>table</title><style>  tr,th {    padding: 30px;  }</style></head><body>  <table id="myTable" border="1" >    <thead>      <tr>        <th>序列</th>        <th>名称</th>        <th>单价</th>        <th>数量</th>      </tr>    </thead>    <tbody>      <tr draggable="true">        <td>1</td>        <td>冰箱</td>        <td>13</td>        <td>14</td>      </tr>      <tr draggable="true">        <td>2</td>        <td>彩电</td>        <td>113</td>        <td>114</td>      </tr>      <tr draggable="true">        <td>3</td>        <td>空调</td>        <td>12</td>        <td>12</td>      </tr>      <tr draggable="true">        <td>4</td>        <td>洗衣机</td>        <td>12</td>        <td>12</td>      </tr>    </tbody>  </table>    <script>    function drag_row_table() {      var EventUtil = {  //跨浏览器的事件处理程序,视情况分别选择以下事件处理程序        addHandler: function(element, type, handler) {          if(element.addEventListener) {  //DOM2级            element.addEventListener(type, handler, false);          }          else if (element.attachEvent) {  //IE方法            element.attachEvent('on' + type, handler);          }          else {  //DOM1级            element["on" + type] = handler;          }        },        getTarget: function(event) {  //获取事件的实际目标(在这里是tr),不同于event.currentTarget和this指向的是绑定事件处理程序的目标,(tbody)          return event.target || event.srcElement;        },

    // 浏览器的默认行为,当拖拽元素悬停在目标元素上时,浏览器默认会拒绝放置(表现为光标变成"禁止"图标❌)    // 这是浏览器的安全机制,防止意外数据交换    // 不加,后面drop就不会触发        preventDefault: function(event) {  //取消事件默认方法          if(event.preventDefault) {              event.preventDefault();          }          else {            event.returnValue = false;  //默认为true,设为falsew为取消默认行为。          }        }      }      var myTable = document.querySelector('#myTable');      var tbody = myTable.querySelector("tbody");  //这里监听的是tbody,而不是tr。目的是利用事件冒泡,减少监听的元素个数,提高性能      var trs = tbody.querySelectorAll("tr");        // dragover 事件在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发。      // 该事件在放置目标上触发      EventUtil.addHandler(tbody, "dragover", function(event) { //默认元素不可放置,这里取消默认,将放置目标修改为可放置的        console.log(event,'dragover');        EventUtil.preventDefault(event);        })      // dragstart 事件在用户开始拖动元素或被选择的文本时调用。      EventUtil.addHandler(tbody, "dragstart", function(event) {  //监听点击的拖动的元素        console.log(event,'dragstart',event.target.rowIndex);        event.dataTransfer.setData("drag_index", event.target.rowIndex); //将被拖元素的信息,传给放置位置      })      // drop 事件在元素或文本选择被放置到有效的放置目标上时触发      EventUtil.addHandler(tbody, "drop", function(event) {  //监听鼠标移动到可放置的放置目标上,松开鼠标的事件       EventUtil.preventDefault(event);  //取消在Firefox 3.5+中,放置事件的默认行为是打开被放置目标上的URL       let drag_index = parseInt(event.dataTransfer.getData("drag_index"));  //获取传过来的被拖元素的信息       let drop_index = EventUtil.getTarget(event).parentNode.rowIndex;  //this为当前触发drop的元素,即放置目标的行下标         tbody.insertBefore(trs[drag_index], EventUtil.getTarget(event).parentNode.nextSibling);   //将被拖元素放到放置目标的兄弟节点上       trs = myTable.querySelectorAll("tr");  //更新变换的tr行信息      })    }    drag_row_table();  </script></body></html>
相关推荐
徐小夕@趣谈前端1 小时前
如何实现多人协同文档编辑器
javascript·vue.js·设计模式·前端框架·开源·编辑器·github
YCOSA20251 小时前
ISO 雨晨 26200.6588 Windows 11 企业版 LTSC 25H2 自用 edge 140.0.3485.81
前端·windows·edge
小白呀白2 小时前
【uni-app】树形结构数据选择框
前端·javascript·uni-app
吃饺子不吃馅2 小时前
深感一事无成,还是踏踏实实做点东西吧
前端·svg·图形学
90后的晨仔2 小时前
Mac 上配置多个 Gitee 账号的完整教程
前端·后端
少年阿闯~~3 小时前
CSS——实现盒子在页面居中
前端·css·html
开发者小天3 小时前
uniapp中封装底部跳转方法
前端·javascript·uni-app
阿波罗尼亚3 小时前
复杂查询:直接查询/子查询/视图/CTE
java·前端·数据库
正义的大古3 小时前
OpenLayers地图交互 -- 章节九:拖拽框交互详解
前端·vue.js·openlayers
三十_A4 小时前
【实录】使用 Verdaccio 从零搭建私有 npm 仓库(含完整步骤及避坑指南)
前端·npm·node.js