拽原理
先介绍一下实现元素拖动需要的坐标属性,offsetLeft、offsetTop 和 clientX、clientY。
offsetLeft 和offsetTop 用在dom节点中,可以返回当前元素距离某个父辈元素左边缘的距离。
clientX、clientY 在事件中使用,返回当事件被触发时鼠标指针向对于浏览器页面的水平坐标。
注:操作当前元素要定义成绝对定位
//css #box{ width: 100px; height: 100px; background: red; position: absolute; } //dom元素 <div id="box"></div>
window.onload = function(){ var drag = document.getElementById('box');//选择dom元素 drag.onmousedown = function(event){ var event = event || window.event; //兼容IE浏览器 // 鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离 var diffX = event.clientX - drag.offsetLeft; var diffY = event.clientY - drag.offsetTop; if(typeof drag.setCapture !== 'undefined'){ drag.setCapture(); } document.onmousemove = function(event){ var event = event || window.event; var moveX = event.clientX - diffX; var moveY = event.clientY - diffY; if(moveX < 0){//判断最左右边临界点 moveX = 0 }else if(moveX > window.innerWidth - drag.offsetWidth){ moveX = window.innerWidth - drag.offsetWidth } if(moveY < 0){//判断最上下边临界点 moveY = 0; }else if(moveY > window.innerHeight - drag.offsetHeight){ moveY = window.innerHeight - drag.offsetHeight } drag.style.left = moveX + 'px'; drag.style.top = moveY + 'px' console.log('x:'+moveX,'y:'+moveY); } document.onmouseup = function(event){ //鼠标松开 清除onmousemove、onmouseup事件 this.onmousemove = null; this.onmouseup = null; //修复低版本ie bug if(typeof drag.releaseCapture!='undefined'){ drag.releaseCapture(); } } } }
拖拽效果
本文中,我们将了解HTML拖放,并借助示例了解其实现.
拖放是一个非常交互式和用户友好的概念,它可以通过抓住对象更轻松地将对象移动到其他位置。这允许用户在元素上单击并按住鼠标按钮,将其拖动到其他位置,然后释放鼠标按钮以将元素放到该位置。在HTML 5中,拖放更容易编码,其中的任何元素都是可拖动的。
拖放事件:有各种拖放事件,其中一些在下面列出:
拖放 Drag and Drop实现步骤:
例1:
<!DOCTYPE HTML>
<html>
<head>
<style>
#getData {
width: 250px;
height: 200px;
padding: 10px;
border: 1px solid #4f4d4d;
}
</style>
<script>
function allowDrop(even) {
even.preventDefault();
}
function drag(even) {
even.dataTransfer.setData("text", even.target.id);
}
function drop(even) {
even.preventDefault();
var fetchData = even.dataTransfer.getData("text");
even.target.appendChild(document.getElementById(fetchData));
}
</script>
</head>
<body>
<h3>Drag the GeekforGeeks image into the rectangle:</h3>
<div id="getData"
ondrop="drop(event)"
ondragover="allowDrop(event)">
</div>
<br>
<img id="dragData"
src="gfg.png"
draggable="true"
ondragstart="drag(event)"
width="250"
height="200">
</body>
</html>
Output:
Dragging the image into the box
拖放过程的数据传递: 当拖放的整个过程发生时,将使用数据传输属性。它用于保存从源拖放到所需位置的数据。这些是与之关联的属性:
例2:
<!DOCTYPE HTML>
<html>
<head>
<title>Drag and Drop box</title>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function dragStart(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function dragDrop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
<style>
#box {
margin: auto;
width: 50%;
height: 200px;
border: 3px solid green;
padding: 10px;
}
#box1,
#box2,
#box3 {
float: left;
margin: 5px;
padding: 10px;
}
#box1 {
width: 50px;
height: 50px;
background-color: #F5B5C5;
}
#box2 {
width: 100px;
height: 100px;
background-color: #B5D5F5;
}
#box3 {
width: 150px;
height: 150px;
background-color: #BEA7CC;
}
p {
font-size: 20px;
font-weight: bold;
text-align: center;
}
.gfg {
font-size: 40px;
color: #009900;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<div class="gfg">GeeksforGeeks</div>
<p>Drag and drop of boxes</p>
<div id="box">
<div id="box1" draggable="true"
ondragstart="dragStart(event)">
</div>
<div id="box2" draggable="true"
ondragstart="dragStart(event)">
</div>
<div id="box3" ondrop="dragDrop(event)"
ondragover="allowDrop(event)">
</div>
</div>
</body>
</html>
说明:
效果:
我们都知道普通的HTML自带的功能相对有限,很多复杂的交互式场景,如果手动去写功能的话会非常的复杂,而且可扩展性差,就拿HTML表格来说,对于初学者或者对于复杂的拖拽式交互编程不熟悉的话会很浪费时间,因此今天就介绍一个第三方的插件——Table-draagger,来轻松实现类似的功能。Table-draagger是用于构建可重排序的拖放表的极简主义纯Javascript库!
https://github.com/sindu12jun/table-dragger
Table-draagger因为其以下几个特征而让拖拽和排序的实现变得如此简单:
可以在npm上获得它:
npm install table-dragger --save
或者引用压缩的js文件
<script src="../node_modules/table-dragger/dist/table-dragger.min.js"></script>
或者尝试开发中的不稳定版本
npm install table-dragger@next --save
请看以下代码:
import tableDragger from 'table-dragger' tableDragger(el, options?)
<table id="table"> <thead> <tr> <th class='handle'>header1</th> <th class='handle'>header2</th> </tr> </thead> <tbody> <tr> <td>conten1</td> <td>conten2</td> </tr> </tbody> </table>
var el = document.getElementById('table'); var dragger = tableDragger(el, { mode: 'row', dragHandler: '.handle', onlyBody: true, }); dragger.on('drop',function(from, to){ console(from); console(to); });
你可以在不设置任何参数的情况下使用默认的拖拽和排序方式,当然以下是你可以配置的选项:
1、将mode设置为column,用户拖动和排序表的列
2、将mode设置为row,用户拖动并排序表的行
3、设置mode为free,用户根据点击后鼠标移动的方向拖动行或列。注意,必须在自由模式下指定dragHandler。
dragHandler是表中的拖动句柄选择器默认情况下,在列模式下,dragHandler是表的第一行;在行模式下,则是第一列。
在行模式下将onlyBody设置为true时,用户只能在tbody中提升行。
下面是返回对象的API
tableDragger(document.querySelector('#event-table'), { mode: 'free', dragHandler: '.handle', onlyBody: true }) .on('drag', () => { console.log('drag'); }) .on('drop', (from, to, el, mode) => { console.log(`drop ${el.nodeName} from ${from} ${mode} to ${to} ${mode}`); }) .on('shadowMove', (from, to, el, mode) => { console.log(`move ${el.nodeName} from ${from} ${mode} to ${to} ${mode}`); }) .on('out', (el, mode) => { console.log(`move out or drop ${el.nodeName} in mode ${mode}`); });
Table-draagger为我们节省了很多手动封装表格排序和拖拽功能的时间,当然目前很多第三方框架已经实现了类似的功能,这更适用于原生的html表格,你还可以通过一些手段记忆用户拖拽,这只是其中一种思路,Enjoy it!~
*请认真填写需求信息,我们会在24小时内与您取得联系。