H5拖拽事件
允许拖拽
图片,带有herf属性的a标签默认可以进行拖拽,其他元素需要设置draggable=‘true’属性。
事件
被拖拽元素的事件
- ondragstart : 鼠标按下,拖拽的一瞬间触发。
- ondrag: 拖拽后,结束前,在这一段时间内会连续触发。
- ondragend:拖拽结束触发
目标元素,被拖拽元素要去的地方。
- ondragenter: 进入目标元素触发,鼠标光标进入
- ondragover: 进入目标,离开目标这段时间中连续触发。
- ondragleave:离开目标元素触发。
- ondrop: 在目标元素上释放鼠标触发。
事件的触发顺序是:start>drag>enter>over>leave||drop>end
*拖放文件到浏览器中时,需要在dragover和drop事件处理器中preventDefault,因为从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的行为是浏览器将当前页面重定向到被拖拽元素所指向的资源上,必须在2个事件处理器中都阻止默认行为
drag和dragover是持续触发的
触发dragstart事件后,其他元素的mousemove,mouseover,mouseenter,mouseleave,mouseout事件均不会被触发了
dataTransfer
-
DataTransfer
对象用于保存拖动并放下(drag and drop)过程中的数据。它可以保存一项或多项数据,这些数据项可以是一种或者多种数据类型。关于拖放的更多信息,请参见 Drag and Drop. -
这个对象可以从所有拖动事件
drag events
的dataTransfer
属性上获取。
常用方法
setData() 用于存放信息
getData() 用于拿取信息
示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>拖拽事件</title>
<style>
*{margin:0;padding:0;}
.box1{
float: left;
background-color: bisque;
width: 120px;
padding: 10px;
}
.box2{
float: right;
background-color: rgb(52, 227, 171);
width: 120px;
padding: 10px;
}
li{
list-style: none;
text-align: center;
height: 30px;
line-height: 30px;
background-color: aqua;
margin: 10px 0 ;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box1">
<li draggable="true" class="li-1">梓恒</li>
<li draggable="true" class="li-2">梓恒爸爸</li>
<li draggable="true" class="li-3">梓恒妈妈</li>
<li draggable="true" class="li-4">梓恒哥哥</li>
<li draggable="true" class="li-5">梓恒妹妹</li>
</div>
<div class="box2"></div>
<script>
let bx1 = document.querySelector('.box1')
let bx2 = document.querySelector('.box2')
/*;[...bx1.children].forEach((li, index)=> {
li.index = index
})*/
// 事件委托处理所有li的dragstart事件,可以少写点事件
// 事件委托通过判断事件源e.target的标签名进行实现。
bx2.ondragstart = bx1.ondragstart = function (e) {
console.log(e);
if(e.target.tagName.toLowerCase() !== 'li') return
e.dataTransfer.setData('ziheng', e.target.className)
}
bx2.ondragover = bx1.ondragover= (e) => {
e.preventDefault();
}
bx2.ondrop = bx1.ondrop= function (e){
let ziheng = e.dataTransfer.getData('ziheng')
let li = document.querySelector('.'+ziheng)
// dom的移动。目标容器去插入
this.appendChild(li)
}
</script>
</body>
</html>
拖拽上传文件
- 文件信息存储在e.dataTransfer.files中
- 文件上传使用 formdata格式
示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>风屿</title>
<style>
*{margin:0;padding:0;}
div{
margin: 50px auto;
width: 500px;
height: 300px;
border: 1px solid #369;
text-align: center;
line-height: 300px;
font-size: 20px;
}
span{
background: #857;
color: white;
cursor: pointer;
}
p{
color: red;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
</head>
<body>
<!-- <div draggable="true"></div> -->
<div>拖拽文件到此或<span>点击上传</span></div>
<p></p>
<script>
// 上传图片: formdata格式上传
let div = document.querySelector('div')
let span = document.querySelector('span')
let p = document.querySelector('p')
// 拖拽
div.ondragover = e => {e.preventDefault()}
div.ondrop = e => {
// 阻止默认行为,以便于拖进来的文件不会被浏览器默认打开
e.preventDefault()
let files = Object.values(e.dataTransfer.files)
let desc = ""
for(let item of files){
desc += `上传的文件名:${item.name}; 大小:${(item.size / 1024).toFixed(1)}kb<br>`
}
p.innerHTML = desc
reqFiles(files)
}
function reqFiles (filesArr) {
// 构造一个formdata对象
let fd = new FormData
for(let item of filesArr){
// 将一个个文件装到formdata对象中,
fd.append("files", item)
}
axios({
url: "http://***************/file",
method: "post",
headers: {
"Content-Type": "multipart/form-data"
},
data: fd
}).then(showImg)
}
//点击上传
span.onclick = () => {
let ipt = document.createElement('input')
ipt.type = "file"
ipt.multiple = true //多个文件上传属性
ipt.name = 'files'
ipt.click()
ipt.onchange = () => {
let files = Object.values(ipt.files)
let desc = ""
for(let item of files){
desc += `上传的文件名:${item.name}; 大小:${(item.size / 1024).toFixed(1)}kb<br>`
}
p.innerHTML = desc
reqFiles(files)
}
}
function showImg (res) {
let data = res.data.files.files
if(Array.isArray(data)) {
for(let item of data){
let img = new Image()
let pathArr = item.path.split("/")
img.src = `http://***************/${pathArr[pathArr.length - 2]}/${pathArr[pathArr.length - 1]}`
console.log(img)
document.body.appendChild(img)
}
}else{
let img = new Image()
let pathArr = data.path.split("/")
img.src = `http://***************/${pathArr[pathArr.length - 2]}/${pathArr[pathArr.length - 1]}`
console.log(img)
document.body.appendChild(img)
}
}
</script>
</body>
</html>