其实HTML5就是新增一些有用的API
让我们更轻松的开发
从而把更多精力都放在业务逻辑上来
这些API的使用也非常简单
不过我的记性不太好
所以还是以博客的形式记录下来(手动滑稽)
今天就来写一下这个拖拽API
默认拖拽
说起拖放,其实最早实现拖放功能的还是IE(IE4)
H5就是在IE实例的基础上指定的拖拽规范
在浏览器中,是有默认拖拽的
比如说图片的拖拽
选中文本的拖拽
链接的拖拽
元素拖拽
浏览器默认允许我们拖拽图像、文本以及链接
让其它元素被拖动也是可以实现的
只需要在元素标签上添加一个属性
<div draggable="true"></div>
当拖拽这个元素的时候,浏览器就会以半透明复本的方式显示
拖拽事件
拖拽事件应该分为两类
一类是被拖拽元素触发的事件
另一类是拖放目标元素触发的事件
<div id="source" draggable="true"></div>
<div id="target"></div> <!-- 样式略 -->
var source = document.getElementById('source');
var target = document.getElementById('target');
拖拽元素
拖拽元素的时候,被拖拽元素会触发以下事件
- dragstart
- drag
- dragend
当鼠标点中元素并且开始移动时,就会触发dragstart事件(类比mousedown)
拖拽过程中会持续不断地触发drag事件(类比mousemove)
松开鼠标取消拖拽时就会触发dragend事件(类比mouseup)
source.ondragstart = function(){
console.log('开始拖拽');
}
source.ondrag = function(){
console.log('拖拽中');
}
source.ondragend = function(){
console.log('拖拽结束');
}
目标元素
当拖拽的元素拖到一个目标元素上时,目标元素会触发以下事件
- dragenter
- dragover
- dragleave
- drop
拖拽元素到目标上,就会触发dragenter事件(类比mouseover)
当拖动元素在目标元素中,就会持续触发dragover事件
离开目标元素,触发dragleave事件(类比mouseout)
若拖放元素到了目标元素中(在目标元素中松开鼠标),就会触发drop事件而不会触发dragleave事件
target.ondragenter = function(){
console.log('拖动进入目标元素');
}
target.ondragover = function(){
console.log('目标元素中拖拽');
}
target.ondragleave = function(){
console.log('拖动离开目标元素');
}
target.ondrop = function(){
console.log('拖放');
}
这时我们会发现元素拖放到目标元素中时
并没有触发drop事件
我们看到了一个特殊的光标(圆环+反斜线)
意思就是无效的拖放
所以导致没有触发drop事件
也就是说元素默认是不能够拖放
只要我们在目标元素的dragover事件中取消默认事件就可以解决问题
target.ondragover = function(e){
console.log('目标元素中拖拽');
e.preventDefault(); //增
}
数据交换
只是简单的拖放毫无意义
我们需要进行数据交换
而这个用语数据交换的对象就是事件对象的属性dataTransfer
dataTransfer的两个核心方法是setData()和getData()
setData()用于设置数据,getData()用语接收数据
event.dataTransfer.setData('text','some text');
var text = event.dataTransfer.getData('text');
//保存在dataTransfer中的数据只能在drop事件处理函数中处理
如果我们拖拽了选中文本
那么浏览器默认就会调用dataTransfer.setData,设置对应文本数据
setData()和getData()就是数据类型的字符串
IE定义的数据类型除了“text”文本类型还有“URL”
H5对它进行了扩展,可以指定各种MIME类型
但为了向后兼容,它同样支持“text”和“URL”
它们会被分别映射为“text/plain”和“text/uri-list”
如果数据保存为URL,浏览器会做特殊处理,把它当成网页链接
(所以拖拽链接到另外的浏览器窗口就会打开网页)
必要的话,我们可以手动保存需要传输的数据
var source = document.getElementById('source');
var target = document.getElementById('target');
source.ondragstart = function(e){
e.dataTransfer.setData('text','传递文本数据');
}
target.ondragover = function(e){
e.preventDefault();
}
target.ondrop = function(e){
console.log(e.dataTransfer.getData('text'));
}
拖拽设置
在dataTransfer中还有两个重要的属性
dropEffect和effectAllowed
dropEffect
dropEffect属性值为字符串,表示被拖动元素可以执行哪一种放置行为
要使用这个属性,必须在dragenter事件处理函数中设置
- none 不能把元素拖放至此(除文本框外全部元素的默认值)
- move 移动到目标
- copy 复制到目标
- link 目标打开拖动元素(拖动元素必须是链接并有URL)
effectAllowed
effectAllowed属性值也是字符串,表示允许拖动元素哪种dropEffect
要使用这个属性,必须在dragst事件处理函数中设置
- uninitialized 没有设置任何拖放行为
- none 不能由任何行为
- copy 仅允许dropEffect值为copy
- link 仅允许dropEffect值为link
- move 仅允许dropEffect值为move
- copyLink 允许dropEffect值为copy和link
- copyMove 允许dropEffect值为copy和move
- linkMove 允许dropEffect值为link和move
- all 允许任意dropEffect
拖拽案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>张高伟拖放api</title>
<style>
#mydiv{
width: 200px;
height: 200px;
border: 1px solid indianred;
background-color: #5c2699;
}
#target{
width: 500px;
height: 500px;
border: 1px solid indianred;
background-color: #c0c0c0;
}
.item{
background-color: cadetblue;
border: 1px solid cornsilk;
}
</style>
</head>
<body>
<!--<div id="mydiv" draggable="true"></div>-->
<!--<div id="target" draggable="true"></div>-->
<ul class="parent_url">
<li draggable="true" class="item">张高伟</li>
<li draggable="true" class="item">李翠翠</li>
<li draggable="true" class="item">王三</li>
<li draggable="true" class="item">赵武</li>
<li draggable="true" class="item">李四</li>
</ul>
</html>
<script>
// var source=document.getElementById('mydiv');
// var target=document.getElementById('target');
//
// source.ondragstart = function(){
// console.log('开始拖拽');
// }
// source.ondrag = function(){
// console.log('拖拽中');
// }
// source.ondragend = function(){
// console.log('拖拽结束');
// }
//
//
target.ondragenter = function(){
console.log('拖动进入目标元素');
}
// target.ondragover = function(){
// console.log('目标元素中拖拽');
// return false;
// }
target.ondragleave = function(){
console.log('拖动离开目标元素');
}
// target.ondrop = function(){
// console.log('拖放');
// this.appendChild(source)
// }
//遍历节点
var item=document.getElementsByClassName('item');
//父级
var parent_url=document.getElementsByClassName('parent_url');
for(var i=0,len=item.length;i<len;i++){
//设置ID方便取
item[i].id='mydiv'+i;
//每个拖放
item[i].ondragstart = function(e){
//存储id
e.dataTransfer.setData('id',this.id)
};
//放之前取消默认事件
item[i].ondragover = function(){
return false;
};
//放事件
item[i].ondrop = function(e){
//去除拖放开始的ID
//console.log(e.dataTransfer.getData('id'))
//放到的位置
console.log(this)
var tuo_id=e.dataTransfer.getData('id');
var tuo=document.getElementById(tuo_id);
//使用insertBefore 达到换位置效果
parent_url[0].insertBefore(tuo,this)
this.style.borderTop="2px solid cornsilk"
}
//拖放中
item[i].ondragenter = function(){
this.style.borderTop="2px solid black"
}
//离开
item[i].ondragleave = function(){
this.style.borderTop="2px solid cornsilk"
}
}
</script>
拖拽图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>张高伟拖放api</title>
<style>
#mydiv{
width: 200px;
height: 200px;
border: 1px solid indianred;
background-color: #5c2699;
}
#target{
width: 500px;
height: 500px;
border: 1px solid indianred;
background-color: #c0c0c0;
}
.item{
background-color: cadetblue;
border: 1px solid cornsilk;
}
</style>
</head>
<body>
<!--<div id="mydiv" draggable="true"></div>-->
<!--<div id="target" draggable="true"></div>-->
<!--<ul class="parent_url">-->
<!--<li draggable="true" class="item">张高伟</li>-->
<!--<li draggable="true" class="item">李翠翠</li>-->
<!--<li draggable="true" class="item">王三</li>-->
<!--<li draggable="true" class="item">赵武</li>-->
<!--<li draggable="true" class="item">李四</li>-->
<!--</ul>-->
</html>
<script>
// var source=document.getElementById('mydiv');
// var target=document.getElementById('target');
//
// source.ondragstart = function(){
// console.log('开始拖拽');
// }
// source.ondrag = function(){
// console.log('拖拽中');
// }
// source.ondragend = function(){
// console.log('拖拽结束');
// }
//
//
target.ondragenter = function(){
console.log('拖动进入目标元素');
}
// target.ondragover = function(){
// console.log('目标元素中拖拽');
// return false;
// }
target.ondragleave = function(){
console.log('拖动离开目标元素');
}
// target.ondrop = function(){
// console.log('拖放');
// this.appendChild(source)
// }
// //遍历节点
// var item=document.getElementsByClassName('item');
// //父级
// var parent_url=document.getElementsByClassName('parent_url');
//
// for(var i=0,len=item.length;i<len;i++){
// //设置ID方便取
// item[i].id='mydiv'+i;
// //每个拖放
// item[i].ondragstart = function(e){
// //存储id
// e.dataTransfer.setData('id',this.id)
// };
// //放之前取消默认事件
// item[i].ondragover = function(){
// return false;
// };
// //放事件
// item[i].ondrop = function(e){
// //去除拖放开始的ID
// //console.log(e.dataTransfer.getData('id'))
// //放到的位置
// console.log(this)
// var tuo_id=e.dataTransfer.getData('id');
// var tuo=document.getElementById(tuo_id);
// //使用insertBefore 达到换位置效果
// parent_url[0].insertBefore(tuo,this)
// this.style.borderTop="2px solid cornsilk"
//
// }
//
// //拖放中
// item[i].ondragenter = function(){
// this.style.borderTop="2px solid black"
// }
//
// //离开
// item[i].ondragleave = function(){
// this.style.borderTop="2px solid cornsilk"
// }
// }
//获取整个html
var html=document.documentElement;
//放之前取消默认事件
html.ondragover = function(){
return false;
};
html.ondrop = function(e){
//禁止图片新链接打开
e.preventDefault();
//表示文件
// console.log(e.dataTransfer.files)
//图片
console.log(e.dataTransfer.files[0])
if(e.dataTransfer.files[0].type.indexOf('image')==-1){
alert('格式错误')
return false;
}
//创建图像
var image=new Image();
//获取图片路径
image.src=window.URL.createObjectURL(e.dataTransfer.files[0])
image.style.top=e.pageY+'px'
image.style.left=e.pageX+'px'
image.style.height='200px'
image.style.width='200px'
// console.log(e.pageY)
// console.log(e.pageX)
//设置class名字
image.className='';
//将图片添加进去
document.body.appendChild(image)
}
</script>