第11章 HTML5中元素的拖放
只要为元素添加draggable属性,就可实现元素的拖放
11.1 拖放基础
11.1.1 使用JavaScript代码实现拖放
1.功能描述
H5页面中,添加两个div,divFrame包含divTitle,用鼠标移到divTitle上时,按下鼠标左键并移动鼠标,可以拖动整个divFrame元素。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用JavaScript代码实现拖放</title>
<style>
#divFrame {
width: 200px;
height: 100px;
border: 1px solid;
position: relative;
}
#divTitle {
border-bottom: 1px solid;
}
#divTitle:hover {
/* cursor: crosshair; */
/* background-color: gray; */
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
var started;
var initX, initY, offsetX, offsetY;
function pageload() {
var divTitle = $$("divTitle");
var divFrame = $$("divFrame");
divFrame.style.left = 30 + "px";
divFrame.style.top = 20 + "px";
//按下鼠标触发
divTitle.onmousedown = function (e) {
started = true;
initX = parseInt(divFrame.style.left);
initY = parseInt(divFrame.style.top);
offsetX = e.clientX;
offsetY = e.clientY;
};
//鼠标移动时触发的事件
divFrame.onmousemove = function (e) {
if (started) {
var x = e.clientX - offsetX + initX;
var y = e.clientY - offsetY + initY;
divFrame.style.left = x + "px";
divFrame.style.top = y + "px";
divTitle.innerHTML = "已拖动";
}
};
//鼠标弹起时触发的事件
divFrame.onmouseup = function () {
started = false;
document.onmousemove = null;
}
}
</script>
</head>
<body onload="pageload();">
<div id="divFrame">
<div id="divTitle">请拖动我</div>
</div>
</body>
</html>
3.页面效果
11.1.2 在HTML5中实现拖放时触发的事件
在H5中拖放很简单,只要将属性draggable设置为true就可以,拖放时触发的相关事件:
- dragstart:被拖放元素,开始拖放时触发
- drag:被拖放元素,正在拖放时触发
- dragenter:经过目标元素,进入某元素时触发
- dragover:经过目标元素,在某元素内移动时触发
- dragleave:目标元素,移出时触发
- drop:目标元素,目标元素完全接收时触发
- dragend:被拖放对象元素,整个拖放操作结束时触发
1.功能描述
新建两个div,将一个元素拖到另一个元素时,页面触发的重要事件状态。
2.代码实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#divDrag {
width: 100px;
height: 100px;
border: 1px solid;
}
#divArea {
float: right;
width: 200px;
height: 200px;
border: 1px solid;
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
function pageload() {
var Drag = $$("divDrag");
var Area = $$("divArea");
//添加被拖放元素的dragstart事件
Drag.addEventListener("dragstart", function (e) {
StatusHandle("元素正在开始拖动。。。")
});
//添加目标元素drop事件
Area.addEventListener("drop", function (e) {
StatusHandle("元素拖入成功!")
});
//添加目标元素的dragleave事件
Area.addEventListener("dragleave", function (e) {
StatusHandle("拖动元素正在离开。。。")
});
}
function StatusHandle(message) {
$$("divTips").innerHTML += message + "<br>";
}
//添加页面的dragover事件
document.ondragover = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//添加页面的ondrop事件
document.ondrop = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
</script>
</head>
<body onload="pageload();">
<div class="wPub">
<div class="wPub">
<div id="divDrag" draggable="true">drag</div>
<div id="divTips">tips:</div>
</div>
<div id="divArea">area</div>
</div>
</body>
</html>
3.页面效果
11.2 dataTransfer对象应用详解
上个案例,被拖放对象没放入目标中,要实现这一功能,需要调用dataTransfer对象。
该对象携带拖放过程中的数据,它拥有许多使用的属性和方法。
dataTransfer对象的属性:
- effectAllowed:设置或返回被允许操作的效果,包括none,copy,copyLink,copyMove,line,move,all等。
- dropEffect:设置或返回当前选定的操作效果类型,若不是effectAllowed的允许范围值,则操作失败。
- items:返回DataTransferItemList对象,即拖动数据。
- types:返回dragstart事件中设置的数据格式,如果拖动文件,返回Files型字符串。
- files:返回被拖动文件FileList清单(如果有)
dataTransfer对象的方法:
- setData(DOMString format,DOMString data):将拖放元素数据存入dataTransfer对象中
- getData(DOMString format):读取存入dataTransfer对象中的数据
- setDragImage(Element img,long x,long y):设置拖放过程中的图标
- clearData(DOMString format):清空dataTransfer对象中指定格式的数据
format形参格式包含如下几种:text/plain(文本文字格式),text/html(HTML页面代码格式),text/xml(XML字符格式),text/url-list(URL格式列表)。
11.2.1 使用setData与getData方法存入与读取拖放数据
1.功能描述
在上一个案例基础上修改代码,当拖放元素触发dragstart事件时,将元素相关数据通过setData()方法存入dataTransfer对象中,在目标接收拖放元素时触发drop事件,该事件中读取dataTransfer对象中存入的数据并放入目标元素中。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用setData与getData方法存入与读取拖放数据</title>
<style>
#divDrag {
width: 100px;
height: 100px;
border: 1px solid;
}
#divArea {
float: right;
width: 200px;
height: 200px;
border: 1px solid;
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
//自定义返回HTML内容函数
function RetDragHTMLById(Id) {
var strHtml = "<div id=" + Id + "></div>";
return strHtml;
}
function pageload() {
var Drag = $$("divDrag");
var Area = $$("divArea");
//添加被拖放元素的dragstart事件
Drag.addEventListener("dragstart", function (e) {
var dtf = e.dataTransfer;
dtf.setData("text/html", RetDragHTMLById(this.id));
}, false);
//添加目标元素drop事件
Area.addEventListener("drop", function (e) {
var dtf = e.dataTransfer;
var strHtml = dtf.getData("text/html");
Area.innerHTML += strHtml;
e.preventDefault();
e.stopPropagation();
}, false);
}
//添加页面的dragover事件
document.ondragover = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//添加页面的ondrop事件
document.ondrop = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
</script>
</head>
<body onload="pageload();">
<div class="wPub">
<div class="wPub">
<div id="divDrag" draggable="true">drag</div>
<div id="divTips">tips:</div>
</div>
<div id="divArea">area</div>
</div>
</body>
</html>
3.页面效果
11.2.2 使用setDragImage方法设置拖放图标
在THML5中,一个元素在被拖放时,还可以改变鼠标的图标,即可以自定义拖放元素时的鼠标图标。要实现这一功能,需要调用dataTransfer对象的setDragImage()方法,调用格式为:
setDragImage(Element img,long x,long y)
其中,参数img是一个元素,表示拖放时显示的元素图标,x表示图标距离鼠标指针的x轴方向的偏移量,y表示图标距离鼠标指针的y轴方向偏移量。
1.功能描述
新创建HTML页面,添加两个
区域,一个作为拖放元素,一个作为目标元素,用于接收拖放来的元素和数据。
选中拖放元素并按住鼠标开始拖放时,鼠标图标将发生变化,拖放完成时,在目标元素中显示“拖动时图标改变”字样。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用setDragImage方法设置拖放图标</title>
<style>
#divDrag {
width: 100px;
height: 100px;
border: 1px solid;
}
#divArea {
float: right;
width: 200px;
height: 200px;
border: 1px solid;
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
function pageload() {
var Drag = $$("divDrag");
var Area = $$("divArea");
var objImg = document.createElement("img");
objImg.src = "img/dog.jpg";
//添加被拖动元素的dragstart事件
Drag.addEventListener("dragstart", function (e) {
var objDtf = e.dataTransfer;
objDtf.setDragImage(objImg, -50, -50);
objDtf.setData("text/plain", "拖动时改变图标");
}, false);
//添加目标元素的drop事件
Area.addEventListener("drop", function (e) {
var objDtf = e.dataTransfer;
var strText = objDtf.getData("text/plain");
Area.textContent += strText;
e.preventDefault();
e.stopPropagation();
}, false)
//添加页面的dragover事件
document.ondragover = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//添加页面的ondrop事件
document.ondrop = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
}
</script>
</head>
<body onload="pageload();">
<div class="wPub">
<div class="wPub">
<div id="divDrag" draggable="true">drag</div>
<div id="divTips">tips:</div>
</div>
<div id="divArea">area</div>
</div>
</body>
</html>
3.页面效果
11.2.3 使用effectAllowed与dropEffect属性设置拖放效果
结合effectAllowed与dropEffect这两个属性,可以自定义拖放过程中的效果。
effectAllowed用于dragstart事件中,绑定被拖放元素,dropEffect用于绑定目标元素。
1.功能描述
在上面例子中,修改代码,拖放元素触发dragstart事件时,将dataTransfer对象的effectAllowed属性设置为move,为目标添加一个dragover事件,当接收数据时,将dropEffect属性值也设为move,从而实现自定义元素拖放效果。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用effectAllowed与dropEffect属性设置拖放效果</title>
<style>
#divDrag {
width: 100px;
height: 100px;
border: 1px solid;
}
#divArea {
float: right;
width: 200px;
height: 200px;
border: 1px solid;
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
function pageload() {
var Drag = $$("divDrag");
var Area = $$("divArea");
var objImg = document.createElement("img");
objImg.src = "img/dog.jpg";
//添加被拖动元素的dragstart事件
Drag.addEventListener("dragstart", function (e) {
var objDtf = e.dataTransfer;
/* objDtf.setDragImage(objImg,-50,-50);
objDtf.setData("text/plain","拖动时改变图标"); */
objDtf.effectAllowed = "copy";
objDtf.setData("text/plain", "拖动时动画效果")
}, false);
//添加目标元素的dragover事件
Area.addEventListener("dragover", function (e) {
var objDtf = e.dataTransfer;
objDtf.dropEffect = "copy";
e.preventDefault();
}, false)
//添加目标元素的drop事件
Area.addEventListener("drop", function (e) {
var objDtf = e.dataTransfer;
var strText = objDtf.getData("text/plain");
Area.textContent += strText;
e.preventDefault();
e.stopPropagation();
}, false)
//添加页面的dragover事件
document.ondragover = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//添加页面的ondrop事件
document.ondrop = function (e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
}
</script>
</head>
<body onload="pageload();">
<div class="wPub">
<div class="wPub">
<div id="divDrag" draggable="true">drag</div>
<div id="divTips">tips:</div>
</div>
<div id="divArea">area</div>
</div>
</body>
</html>
3.页面效果
11.3 拖放应用实战
拖放功能重要,借助API可以实现相对复杂的功能与特效,例如:电商平台中的购物车,可以将选中的商品以拖放的方式放入购物车中,同时接收拖来的数据,检测重复性并自动计价。在相册管理中的图片以拖放的方式放入回收站中,改变回收站图标样式,删除图片。
11.3.1 购物车的实现
通常情况,除了点击商品的购买练级额,也可以拖放商品到购物车中。
1.功能描述
创建H5,页面中展示4件图书商品,用户可以任选一件,按住鼠标,以拖放的方式将选择的商品放入购物车中,同时,购物车接收拖来的商品数据,自动增加一条选择记录,并显示商品的基本信息。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拖放购物车</title>
<style>
ul#ulBook {
height: 200px;
clear: both;
}
ul#ulBook li {
list-style-type: none;
float: left;
margin: 5px;
padding: 3px;
text-align: center;
border: 1px solid;
width: 60px;
height: 80px;
}
#ulCart {
height: 200px;
list-style-type: none;
/* border: 1px dotted; */
}
.lg {
background-color: lightgray;
}
span {
font-weight: bold;
display: inline-block;
width: 100px;
border: 1px solid;
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
function pageload() {
//获取全部图书商品
var Drag = document.getElementsByTagName("img");
//遍历每个图书商品
for (var i = 0; i < Drag.length; i++) {
//为每个商品添加dragstart事件
Drag[i].addEventListener("dragstart", function (e) {
var objDtf = e.dataTransfer;
objDtf.setData("text/html", addCard(this.title, this.alt, 1));
}, false)
}
var Cart = $$("ulCart");
//添加目标元素的drop事件
Cart.addEventListener("drop", function (e) {
var objDtf = e.dataTransfer;
var strHtml = objDtf.getData("text/html");
Cart.innerHTML += strHtml;
e.preventDefault();
e.stopPropagation();
}, false);
}
//添加页面dragover事件
document.ondragover = function (e) {
e.preventDefault();
}
//添加页面drop事件
document.ondrop = function (e) {
e.preventDefault();
}
//自定义向购物车中添加记录的函数
function addCard(a, b, c) {
var strHtml = "<li class='liC'>";
strHtml += "<span>" + a + "</span>";
strHtml += "<span>" + b + "</span>";
strHtml += "<span>" + c + "</span>";
strHtml += "<span>" + b * c + "</span></li>";
return strHtml;
}
</script>
</head>
<body onload="pageload();">
<ul id="ulBook">
<li class="liF">
<img src="img/实战.jpg" id="img02" alt="42" title="2020年作品" draggable="true" />
</li>
<li class="liF">
<img src="img/JS高级.jpg" id="img03" alt="56" title="2021年作品" draggable="true" />
</li>
<li class="liF">
<img src="img/并发编程.jpg" id="img04" alt="52" title="2022年作品" draggable="true" />
</li>
<li class="liF">
<img src="img/计算机网络.jpg" id="img05" alt="59" title="2023年作品" draggable="true" />
</li>
</ul>
<ul id="ulCart">
<li>
<span class="lg">书名</span><span class="lg">定价</span><span class="lg">数量</span><span class="lg">总价</span>
</li>
</ul>
</body>
</html>
</body> </html>
3.页面效果
11.3.2 相册的管理
除了上述应用,还可以将相册中某张图片以拖放的方式放入回收站,从而实现管理相册的功能。
1.功能描述
新建H5,以列表方式展示相册中的3张图片,用户可以任选一张,按住鼠标,以拖动的方式放入右下角回收站,拖放成功后,将在页面中显示删除图片的记录数,同时回收站样式也发生相应变化。
2.实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用拖放API将图片拖入回收站</title>
<style>
* {
list-style-type: none;
}
ul {
width: 400px;
height: 200px;
border: 1px dotted;
}
ul li {
float: left;
margin: 5px;
padding: 3px;
text-align: center;
border: 1px solid;
width: 60px;
height: 80px;
}
#divRecycle {
height: 200px;
width: 200px;
border: 1px solid;
border-radius: 100px;
background-image: url(img/空杯.png);
}
#divRecycle.HaveRyl {
background-image: url(img/实杯.png);
}
</style>
<script>
function $$(id) {
return document.getElementById(id);
}
var intDeleteNum = 0;
function pageload() {
//获取全部图片信息
var Drag = document.getElementsByTagName("li");
//遍历图片
for (var i = 0; i < Drag.length; i++) {
//为每一张图片添加dragstart事件
Drag[i].addEventListener("dragstart", function (e) {
var dtf = e.dataTransfer;
dtf.setData("text/plain", this.id);
}, false)
}
var Recy = $$("divRecycle");
//添加目标元素的drop事件
Recy.addEventListener("drop", function (e) {
var dtf = e.dataTransfer;
var intVal = dtf.getData("text/plain");
Drag_Event(intVal);
Recy.className = "HaveRyl";
}, false);
}
//添加页面dragover事件
document.ondragover = function (e) {
e.preventDefault();
}
//添加页面drop事件
document.ondrop = function (e) {
e.preventDefault();
}
function Drag_Event(id) {
var Node = $$(id);
Node.parentNode.removeChild(Node);
intDeleteNum++;
$$("pStatus").innerHTML = "已成功删除" + intDeleteNum + "张图片!";
}
</script>
</head>
<body onload="pageload();">
<div class="wPub">
<ul>
<li id="li01">
<img src="img/实战.jpg" draggable />
</li>
<li id="li02">
<img src="img/JS高级.jpg" draggable />
</li>
<li id="li03">
<img src="img/并发编程.jpg" draggable />
</li>
</ul>
<p id="pStatus">提示:</p>
<div id="divRecycle"></div>
</div>
</body>
</html>
3.页面效果
对应文档:【有道云笔记】《HTML5实战》
https://note.youdao.com/s/3ubs1KG8
如需源码,请私信我!!!