拖放概念:
拖放是HTML5标准的一部分,任何元素都能够拖放。
操作:拖拽:Drag、 释放:Drop
注意:拖拽指的是鼠标点击源对象后一直移动对象不松手,一但松手即释放了
拖放使用:
- 设置元素为可拖放:draggable 属性:标签元素要设置draggable=true,否则不会有效果 (注意:链接和图片默认是可拖动的,不需要 draggable 属性。)
常用API:
被拖动的源对象可以触发的事件:
ondragstart
:源对象开始被拖动ondrag
:源对象被拖动过程中(鼠标可能在移动也可能未移动)ondragend
:源对象被拖动结束
拖动源对象可以进入到上方的目标对象可以触发的事件:
ondragenter
:目标对象被源对象拖动着进入ondragover
:目标对象被源对象拖动着悬停在上方ondragleave
:源对象拖动着离开了目标对象ondrop
:源对象拖动着在目标对象上方释放/松手
DataTransfer
在进行拖放操作时,DataTransfer
对象用来保存被拖动的数据(它可以保存一项或多项数据、一种或者多种数据类型)
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
html {
font-size: 10px;
}
div {
width: 20rem;
height: 20rem;
background-color: red;
float: left;
margin: 1rem;
}
div:nth-child(2) {
background-color: green;
}
div:nth-child(3) {
background-color: blue;
}
#box {
height: 4.5rem;
background-color: purple;
line-height: 4.5rem;
text-align: center;
cursor: move;
font-size: 1.6rem;
color: #fff;
}
</style>
</head>
<body>
<div id="div1">
<p id="box" draggable="true">拖拽内容</p>
</div>
<div id="div2"></div>
<div id="div3"></div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
let box = $('#box').get(0);
box.ondragstart = function () {
console.log('该对象被开始拖拽');
};
box.ondrag = function () {
console.log('该对象被拖动中');
};
box.ondragend = function () {
console.log('该对象拖动结束');
};
// 2. 找到目标对象
let target = $('#div2').get(0);
target.ondragenter = function () {
console.log('进入目标对象')
};
target.ondragover = function (e) {
console.log('悬浮在目标对象上方');
// 清除默认的行为
// e.preventDefault();
return false;
};
target.ondragleave = function () {
console.log('离开目标对象')
};
//
target.ondrop = function () {
this.appendChild(box);
}
});
</script>
</body>
</html>
需要注意:想要完成拖放需要在ondragover
中清除默认事件 return false否则ondrop
不能生效。
当然上面只是一个盒子,如果拖放多个盒子的话需要改善一下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {margin: 0;padding: 0;}
html{
font-size: 10px;
}
div {
width: 20rem;
height: 20rem;
background-color: red;
float: left;
margin: 1rem;
}
div:nth-child(2){
background-color: green;
}
div:nth-child(3){
background-color: blue;
}
p{
height: 4.5rem;
background-color: purple;
line-height: 4.5rem;
text-align: center;
cursor: move;
font-size: 1.6rem;
color: #fff;
border-bottom: 1px solid #fff;
}
</style>
</head>
<body>
<div id="div1">
<p id="box1" draggable="true">拖拽内容1</p>
<p id="box2" draggable="true">拖拽内容2</p>
<p id="box3" draggable="true">拖拽内容3</p>
</div>
<div id="div2"></div>
<div id="div3"></div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
let obj = null;
document.ondragstart = function (e) {
console.log('该对象被开始拖拽');
obj = e.target;
};
document.ondrag = function () {
console.log('该对象被拖动中');
};
document.ondragend = function () {
console.log('该对象拖动结束');
};
// 2. 找到目标对象
let target = $('#div2').get(0);
target.ondragenter = function () {
console.log('进入目标对象')
};
target.ondragover = function (e) {
console.log('悬浮在目标对象上方');
// 清除默认的行为
// e.preventDefault();
return false;
};
target.ondragleave = function () {
console.log('离开目标对象')
};
target.ondrop = function () {
this.appendChild(obj);
}
});
</script>
</body>
</html>
用e.target来获取事件标签再将标签作为实参传入到appendChild
中即可,但是此方法还有一个缺点就是只能拖放入制定的一个盒子当中。所以需要最后一部优化:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {margin: 0;padding: 0;}
html{
font-size: 10px;
}
div {
width: 20rem;
height: 20rem;
background-color: red;
float: left;
margin: 1rem;
}
div:nth-child(2){
background-color: green;
}
div:nth-child(3){
background-color: blue;
}
p{
height: 4.5rem;
background-color: purple;
line-height: 4.5rem;
text-align: center;
cursor: move;
font-size: 1.6rem;
color: #fff;
border-bottom: 1px solid #fff;
}
</style>
</head>
<body>
<div id="div1">
<p id="box1" draggable="true">拖拽内容1</p>
<p id="box2" draggable="true">拖拽内容2</p>
<p id="box3" draggable="true">拖拽内容3</p>
</div>
<div id="div2"></div>
<div id="div3"></div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
document.ondragstart = function (e) {
console.log('该对象被开始拖拽');
e.dataTransfer.setData('domId', e.target.id)
};
document.ondrag = function () {
console.log('该对象被拖动中');
};
document.ondragend = function () {
console.log('该对象拖动结束');
};
// 2. 找到目标对象
document.ondragenter = function () {
console.log('进入目标对象')
};
document.ondragover = function (e) {
console.log('悬浮在目标对象上方');
// 清除默认的行为
// e.preventDefault();
return false;
};
document.ondragleave = function () {
console.log('离开目标对象')
};
document.ondrop = function (e) {
let id = e.dataTransfer.getData('domId');
// console.log(id);
e.target.appendChild(document.getElementById(id));
}
});
</script>
</body>
</html>
上面说到 拖拽中有一项指令:DataTransfer
在进行拖放操作时,DataTransfer
对象用来保存被拖动的数据(它可以保存一项或多项数据、一种或者多种数据类型)
所以我们可以通过 e.dataTransfer.setData('domId', e.target.id)
的方式来保存拖拽盒子的id
然后再ondrop
松手时 获取松手的 元素(e.target) 然后像其中添加元素,添加的元素可以通过之前被拖动的数据中取出e.dataTransfer.getData('domId')
;到此就大功告成啦~
我们不仅可以把box放入div中 还能将box放入body中或者其他标签中,不过值得注意的是如果放入html中貌似是会消失掉的,应该是因为内容都应该写在body中。
补充一点,松手时执行e.target.appendChild(document.getElementById(id));
系统会自动将之前的标签转移到盒子中,不会出现复制的情况这点不用担心