300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 原生Javascript实现表格行上下拖拽

原生Javascript实现表格行上下拖拽

时间:2021-07-26 14:22:57

相关推荐

原生Javascript实现表格行上下拖拽

拖放事件:

拖动元素时,依次触发的事件

dragstart 按下鼠标并移动时触发drag 拖动期间持续触发dragend 松开鼠标触发

拖动到有效的放置目标上时,依次触发

dragenter 元素被拖到放置目标上dragover 被拖元素在放置目标内移动,持续触发dragleave 元素被拖到放置目标外触发drop 元素被拖到有效的放置目标上(默认无效),并松开鼠标触发

实现代码:

<!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;},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"); EventUtil.addHandler(tbody, "dragover", function(event) {//默认元素不可放置,这里取消默认,将放置目标修改为可放置的EventUtil.preventDefault(event); })EventUtil.addHandler(tbody, "dragstart", function(event) {//监听点击的拖动的元素event.dataTransfer.setData("drag_index", event.target.rowIndex); //将被拖元素的信息,传给放置位置})EventUtil.addHandler(tbody, "drop", function(event) {//监听鼠标移动到可放置的放置目标上,松开鼠标的事件EventUtil.preventDefault(event); //取消在Firefox 3.5+中,放置事件的默认行为是打开被放置目标上的URLlet 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>

效果:

这里遇到的坑是,querySelectorAll()方法的底层实现是类似于一组元素的快照,而不是动态查询的(即更新文档结构时,对应的变量也自动更新),为的是避免使用NodeList对象引起的性能问题。因此我们得手动更新querySelectorAll()方法的变量。

符合动态查询的方法有getElementsByTagName()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。