表格拖拽原生实现

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>
相关推荐
Lsx_6 分钟前
MultiRepo 和 Monorepo:代码管理的演进与选择
前端·javascript·架构
潘多编程17 分钟前
构建企业级Web应用:AWS全栈架构深度解析
前端·架构·aws
裕波21 分钟前
Vue 与 Vite 生态最新进展:迈向一体化与智能化的未来
前端·vue.js
destinying38 分钟前
当部分请求失败时,前端如何保证用户体验不崩溃?
前端·javascript·程序员
幼儿园技术家44 分钟前
Diff算法的简单介绍
前端
陈随易44 分钟前
为VSCode扩展开发量身打造的UI库 - vscode-elements
前端·后端·程序员
子壹1 小时前
大文件分片上传
javascript·node.js
叁金Coder1 小时前
业务系统跳转Nacos免登录方案实践
前端·javascript·nginx·nacos
蓝倾1 小时前
京东商品销量数据如何获取?API接口调用操作详解
前端·api·fastapi
stoneship1 小时前
满帮微前端
前端