1. 常用拖放事件
进行拖放操作时需要对放置的元素阻止默认行为。
因为浏览器默认阻止拖放。
ev.preventDefault()
这句通常写在dragover,dragenter,dragleave,drop绑定的事件中。
源元素事件:
dragstart 拖放开始
drag 正在拖拽
dragend 整个拖放过程结束
目标元素事件:
dragover 拖拽经过目标元素上
dragenter 拖拽经过目标元素上
dragleave 离开可目标元素
drop 已放置在目标元素上
2. web API接口
DataTransfer:DataTransfer对象用于保存拖动并放下(drag and drop)过程中的数据。它可以保存一项或多项数据,这些数据项可以是一种或者多种数据类型。参考链接:(MDN-DataTransfer)
dataTransfer.setData:设置给定类型的数据。如果该类型的数据不存在,则将其添加到末尾,以便类型列表中的最后一项将是新的格式。如果该类型的数据已经存在,则在相同位置替换现有数据。
dataTransfer.getData:检索给定类型的数据,如果该类型的数据不存在或 data transfer不包含数据,则返回空字符串。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>DataTransfer</title>
<style>
#source {
border: 1px solid red;
padding: 0.5em;
width: 50%;
}
#target {
border: 2px solid;
padding: 2em;
width: 50%;
}
</style>
</head>
<body>
<h2 draggable="true" id="source" ondragstart="dragstart(event)">拖动此元素</h2>
<div id="target" ondragover="dragover(event)" ondrop="drop(event)">
<span>放置区域</span>
</div>
<script>
function dragstart(ev) {
ev.target.style.border = "dashed";
ev.dataTransfer.setData('id',ev.target.id)
ev.target.innerHTML = "正在拖动"
}
function dragover(ev) {
ev.preventDefault()
}
function drop(ev) {
ev.preventDefault()
var data = ev.dataTransfer.getData('id')
var source = document.getElementById(data)
source.innerHTML = "拖动此元素"
source.style.border = "1px solid red"
ev.target.appendChild(document.getElementById(data))
ev.dataTransfer.clearData()
console.log(ev.dataTransfer.getData("text"))
}
</script>
</body>
</html>
3. 一个完整的拖放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dropzone {
border: 3px solid purple;
background-color: cadetblue;
height: 80px;
width: 500px;
}
#source {
border: 1px solid;
background-color: coral;
width: 200px;
}
</style>
</head>
<body>
<h2 draggable="true" id="source">拖动这个元素</h2>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<script>
var flag_drag = true
var flag_dragend = true
var flag_dragover = true
var flag_dragstart = true
var flag_dragenter = true
var flag_dragleave = true
var flag_drop = true
document.addEventListener('dragstart', function (ev) {
if (flag_dragstart) {
console.log("dragstart事件触发")
flag_dragstart = false
}
ev.dataTransfer.setData('text/plain', ev.target.id)
})
document.addEventListener('drag', function (ev) {
if (flag_drag) { // 删除if语句drag事件将持续触发
console.log("drag事件持续触发")
flag_drag = false
}
})
document.addEventListener('dragend', function (ev) {
if (flag_dragend) {
console.log("dragend事件触发")
flag_dragend = false
}
})
document.addEventListener('dragover', function (ev) {
ev.preventDefault() // 阻止浏览器默认禁止拖放的行为
if (flag_dragover) {// 删除if语句dragover事件将持续触发
console.log("dragover事件持续触发")
flag_dragover = false
}
})
document.addEventListener('dragenter', function (ev) {
if (flag_dragenter) {
console.log("dragenter事件触发")
flag_dragenter = false
}
})
document.addEventListener('dragleave', function (ev) {
if (flag_dragleave) {
console.log("dragleave事件触发")
flag_dragleave = false
}
})
document.addEventListener('drop', function (ev) {
if (flag_drop) {
console.log("drop事件触发")
flag_drop = false
}
ev.preventDefault()
// 设置只在dropzone中可以放置,document中不能放置
if (ev.target.className === "dropzone") {
var data = ev.dataTransfer.getData('text')
ev.target.appendChild(document.getElementById(data))
}
})
</script>
</body>
</html>