背景
最近公司一个项目通过ftp连接远程ftp服务器,文件传输界面本地与远端文件表格需要实现数据互相拖动达到下载与上传的效果。虽然网上已经有很多现成的插件,但是我希望直接通过原生js实现,不想引入第三方的js文件。所以通过原生js实现了一个对 element 表格数据互相拖动的小 demo。以此记录一下。
Demo 代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表格行数据拖动</title>
</head>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
</style>
<body>
<div id="app">
<el-table highlight-current-row :data="localTableData" id="local"
style="width: 40%;float: left;user-select: none;">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
<div style="width: 20px;float: left;height: 100px;background-color: #ffffff;"></div>
<el-table highlight-current-row :data="remoteTableData" id="remote"
style="width: 50%;user-select: none;">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.js"></script>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data: function() {
return {
visible: false,
localTableData: [{
date: '2016-05-02',
name: '张大头',
address: '南京市天湖区金沙江路 1518 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}],
remoteTableData: [{
date: '2016-05-01',
name: 'lisi',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: 'wangwu',
address: '上海市普陀区金沙江路 1517 弄'
}],
menus: [{
name: "菜单一",
operType: 1,
icon: "el-icon-upload2"
},
{
name: "菜单二",
operType: 2,
icon: "el-icon-download"
},
],
local:'',
}
},
mounted() {
this.remoteTable();
this.localTable()
},
methods: {
remoteTable(){
let row = document.querySelectorAll("#remote .el-table__row");
for (let i = 0; i < row.length; i++) {
row[i].onmousedown = (e) => {
let c = e.target.parentElement.parentElement.firstChild.firstChild.innerText
let rowdata = this.remoteTableData.filter(d => d.date == c);
if(rowdata && rowdata.length){
this.local = rowdata[0]
var body = document.querySelector("body")
body.style.cursor= "url(https://www.baidu.com/favicon.ico),move"
}
// 鼠标松开事件
document.onmouseup = (e) => {
var body = document.querySelector("body")
body.style.cursor= "default"
let a = document.getElementById("local");
if(e.pageX > a.offsetLeft && e.pageX < a.clientWidth + a.offsetLeft
&& e.pageY > a.offsetTop && e.pageY < a.offsetTop + a.clientHeight){
this.localTableData.push(this.local)
setTimeout(() => {
this.localTable()
},1)
}
document.onmousemove = null;
document.onmouseup = null;
row[i].releaseCapture && row[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
};
}
}
},
localTable(){
let row = document.querySelectorAll("#local .el-table__row");
for (let i = 0; i < row.length; i++) {
row[i].onmousedown = (e) => {
let c = e.target.parentElement.parentElement.firstChild.firstChild.innerText
let rowdata = this.localTableData.filter(d => d.date == c);
if(rowdata && rowdata.length){
this.local = rowdata[0]
var body = document.querySelector("body")
body.style.cursor= "url(https://www.baidu.com/favicon.ico),move"
}
// 鼠标松开事件
document.onmouseup = (e) => {
var body = document.querySelector("body")
body.style.cursor= "default"
let a = document.getElementById("remote");
if(e.pageX > a.offsetLeft && e.pageX < a.clientWidth + a.offsetLeft
&& e.pageY > a.offsetTop && e.pageY < a.offsetTop + a.clientHeight){
this.remoteTableData.push(this.local)
setTimeout(() => {
this.remoteTable()
},1)
}
document.onmousemove = null;
document.onmouseup = null;
row[i].releaseCapture && row[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
};
}
}
}
}
})
</script>
</body>
</html>
具体的实现思路
- 首先通过 document 获取页面表格行元素,给行元素添加鼠标按下的事件
- 鼠标按下时改变鼠标的样式可以给用户直观的体验知道已经选中了表格行行数据,通过js获取到当前选择行的数据
- 通过监听到鼠标抬起的事件获取到目前鼠标的x轴与y轴的坐标位置,并且将鼠标的样式重置回默认的状态
- 获取到另一表格的宽度与高度以及距离页面顶部与页面左边的距离可以计算出表格区域的位置
- 比较 x与 y坐标是否落入另一个表格内的位置
- 当落入表格内的位置时即可以做相应的业务工作,将数据添加至另一个表格中
实现效果