您的位置:首页 > Web前端 > HTML5

HTML5高阶实例之Drag&Drop

2018-03-17 22:53 381 查看
更新日期:2018年3月27日21:53:27

1、原生拖放-概述

对于拖放事件而言,默认情况下,浏览器不会在拖动期间改变被拖动元素的外观,但你可以自己修改。不过,大多数浏览器会为正被拖动的元素创建一个半透明的副本,这个副本始终随着光标移动。如下图所示。

>

默认情况下,图片、链接和文本是可以拖动的,也就是说img标签、a标签和选中的文字可以被拖动。

>

HTML5为所有HTML元素规定了一个draggable属性,img标签、a标签的默认值是true,其他元素默认值是false。



所有元素都支持放置目标事件,但默认是不允许放置的,即默认不会触发drop事件。如果想让某元素成为有效的放置目标,需要重写dragenter、dragover、drop事件。

2、使用注意事项

相关事件如下表格

事件名称简要描述是否必须重写
dragstart按下并移动鼠标,被拖动元素此时触发该事件,触发一次
dragenter元素拖动到放置目标上,触发一次
dragover被拖动元素进入放置目标的范围内移动时,持续触发多次
drop被拖动元素放入了放置目标中,触发一次
dataTransfer对象

dataTransfer对象,它是事件对象的一个属性,用于从被拖动元素放置目标传递字符串格式的数据。由于它是事件对象的属性(event.dataTransfer),所以只能在拖放事件的事件处理程序中访问。dataTransfer对象两个主要方法:

event.dataTransfer.setData();

event.dataTransfer.getData();

>

注意:在dragstart事件中通过event.dataTransfer.setData(‘text’,’wanshaobo’)保存在dataTransfer对象中的数据,只能在drop事件处理程序中读取event.dataTransfer.getData(‘text’)

3、实例一

概述:实现任务进度完成情况的可视化方案,包括未开始、进行中和已完成,任务标签可以在不同进度框中随意拖放。

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5-drag&drop</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
#container{
/*font-size: 0;*/
clear: both;
}
.dropTarget{
width: 200px;
height: 500px;
background: #fff;
bor
1249d
der: 1px solid deeppink;
/*display: inline-block;*/
margin-left: 20px;
margin-top: 20px;
float: left;
text-align: center;
}
#draggable{
/*font-size: 0;*/
/*子元素人为设置为inline-block,父元素需要设置0字号以消除子元素间距*/
}
.child{
width: 200px;
height: 40px;
color: #fff;
font-size: 14px;
text-align: center;
line-height: 40px;
border-radius: 20px;
margin-top: 5px;
}
.child-img{
width: 100px;
height: 100px;
}
.title{
margin-left: 20px;
float: left;
width: 200px;
text-align: center;
border: 1px solid #11baaa;
line-height: 30px;
border-radius: 15px;
color: #aaccbb;
}
.clearBoth{
clear: both;
}
#top-title{
width: 640px;
text-align: center;
line-height: 50px;
font-size: 22px;
color: deeppink;
font-weight: bolder;
margin-left: 20px;
}
</style>
<body>
<div id="top-title">我的一天</div>
<div class="clearBoth">
<div class="title">准备做的事情</div>
<div class="title">正在做的事情</div>
<div class="title">已做完的事情</div>
</div>
<div id="container">
<div id="start" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">
<img id="five" class="child-img" src="./wsb.jpg" alt="" ondragstart="dragstart(event)">
<div id="one" class="child" style="background: #ff7777" draggable="true" ondragstart="dragstart(event)">洗漱</div>
<div id="two" class="child" style="background: #aaccbb" draggable="true" ondragstart="dragstart(event)">吃早饭</div>
<div id="three" class="child" style="background: #ad8888" draggable="true" ondragstart="dragstart(event)">坐公交去上班</div>
<div id="four" class="child" style="background: #f00aaa" draggable="true" ondragstart="dragstart(event)">到公司了打卡</div>
</div>
<div id="doing" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">

</div>
<div id="end" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">

</div>
</div>
</body>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
function dragstart(ev) {
ev.dataTransfer.setData("Text",ev.target.id);//获取拖动元素实例
}
function dragenter(ev) {
ev.preventDefault();//dragenter事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
}
function dragover(ev) {
ev.preventDefault();//dragover事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
}
//必须重写dragenter事件和dragover事件,阻止这两个事件的默认行为触发,才能触发drop事件
function drop(ev) {
ev.preventDefault();//在Firefox3.5+中,放置事件的默认行为是打开被放到放置目标上的URL,为了兼容性,需要取消drop事件的默认行为
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</html>


作品如下



4、实例二

概述:子元素在父元素中随意拖放,但不能超出父元素。

分析:子元素超出父元素分为两种情况,第一,释放子元素时鼠标已经出界;第二,释放子元素时鼠标没有出界,但子元素出界;

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5-drag&drop</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
.dropTarget{
width: 600px;
height: 400px;
background: #fff;
border: 1px solid deeppink;
margin-left: 20px;
margin-top: 40px;
}
#child{
width: 100px;
height: 60px;
position: relative;
box-sizing: border-box;
background: #ff7777;
}
</style>
<body>
<div id="start" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">
<div
id="child"
onmousedown="mousedown(event)"
draggable="true"
ondragstart="dragstart(event)"
ondrag="drag(event)"
ondragend="dragend(event)"

></div>
</div>
</body>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
var relativeX = 0;//可移动元素相对于父元素的位置
var relativeY = 0;
var mousedownX = 0;//鼠标在可移动元素上单击时,相对于该元素的位置 0 < x < 100
var mousedownY = 0;
var draggableEle = document.getElementById('child');
function dragstart(ev) {
//ev.dataTransfer.setData("Text",ev.target.id);//获取拖动元素实例
}
function drag(ev) {

}
function mousedown(ev) {
//ev对象下offsetX offsetY鼠标在该移动元素上的位置
mousedownX = ev.offsetX;
mousedownY = ev.offsetY;
}
function dragend(ev) {
//ev对象下screenX clientX pageX x都相同
//ev对象下clientY pageY y都相同,相对于可视区域的垂直位置;但screenY不同,screenY是相对于屏幕的垂直位置
//ev对象下offsetX offsetY鼠标移动的位移+鼠标在该移动元素上的位置
//DOM元素属性操作方法 getAttribute()、setAttribute()、removeAttribute()
//DOM元素样式操作方法 elm.style.color 获取和赋值
relativeX += ev.offsetX - mousedownX;
relativeY += ev.offsetY - mousedownY;
//draggableEle.setAttribute('style','left:'+ relativeX + 'px;top:' + relativeY + 'px');//失效,因为重置了所有属性,丢失了宽高
//水平方向
if(ev.screenX <= 20 || ev.screenX >= 620){//鼠标出界
if(ev.screenX <= 20){//父元素相对于屏幕的margin-left: 20px;
draggableEle.style.left = 0 + 'px';
relativeX = 0;//注意:此处没有px
}else if(ev.screenX >= 620){//父元素宽600 + 20
draggableEle.style.left = 500 + 'px';//600-100
relativeX = 500;//注意:此处没有px
}else{
draggableEle.style.left = relativeX + 'px';
}
}else{//元素出界鼠标没有出界
if(ev.screenX <= mousedownX + 20){
draggableEle.style.left = 0 + 'px';
relativeX = 0;//注意:此处没有px
}else if(ev.screenX >= mousedownX + 520){//600-100+20
draggableEle.style.left = 500 + 'px';
relativeX = 500;//注意:此处没有px
}else{
draggableEle.style.left = relativeX + 'px';
}

}
//垂直方向
if(ev.pageY <= 20 || ev.pageY >= 440){//鼠标出界
if(ev.pageY <= 40){
draggableEle.style.top = 0 + 'px';
relativeY = 0;//注意:此处没有px
}else if(ev.pageY >= 440){
draggableEle.style.top = 340 + 'px';
relativeY = 340;//注意:此处没有px
}else{
draggableEle.style.top = relativeY + 'px';
}
}else{//元素出界鼠标没有出界
if(ev.pageY <= mousedownY + 40){
draggableEle.style.top = 0 + 'px';
relativeY = 0;//注意:此处没有px
}else if(ev.pageY >= mousedownY + 380){//400-60+40
draggableEle.style.top = 340 + 'px';
relativeY = 340;//注意:此处没有px
}else{
draggableEle.style.top = relativeY + 'px';
}
}
}
//必须重写dragenter事件和dragover事件,阻止这两个事件的默认行为触发,才能触发drop事件
function dragenter(ev) {
ev.preventDefault();//dragenter事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
}
function dragover(ev) {
ev.preventDefault();//dragover事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
}
//在Firefox3.5+中,放置事件的默认行为是打开被放到放置目标上的URL,为了兼容性,需要取消drop事件的默认行为
function drop(ev) {
ev.preventDefault();
}
</script>
</html>


作品如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: