Basic syntax and events
The draggable attribute specifies whether the element is draggable. Must be set, otherwise there will be no drag effect and event triggering
Tip: Links and images are draggable by default.
Tip: The draggable attribute is often used in drag and drop operations
grammar
<element draggable="true|false|auto">
value | describe |
---|---|
true | Specifies that the element is draggable. |
false | Specifies that the element is not draggable. |
auto | Use the browser's default features. |
The following events are triggered during the drag and drop process:
Trigger an event on the drag target (source element) and act on the dragged element
- ondragstart - triggers when dragging an element starts
- ondrag - Fires when the element is being dragged
- ondragend - fired after the user has finished dragging the element
<div id="app">
<div class="drag" draggable="true"></div>
<div class="target"></div>
</div>
<script>
const drag = document.querySelector('.drag')
const target = document.querySelector('.target')
drag.addEventListener('dragstart', ondragstart)
drag.addEventListener('drag', ondrag)
drag.addEventListener('dragend', ondragend)
function ondragstart(event) {
console.log('开始拖动')
}
function ondrag(event) {
console.log('正在拖动')
}
function ondragend(event) {
console.log('完成拖动')
}
</script>
Acts on target element
- ondragenter - Triggered when the source element dragged by the mouse enters the scope of its container (triggered when the source element dragged by the mouse enters the scope of the target container)
- ondragover - triggered when the dragged source object is dragged within the target container
- ondragleave - triggered when the dragged object leaves the target container
- ondrop - triggered when the mouse is released
Event.preventDefault
To prevent the default event, the preventDefault method must be executed in ondragover, otherwise ondrop will not be triggered.
<div id="app">
<div class="drag" draggable="true"></div>
<div class="target"></div>
</div>
<script>
const drag = document.querySelector('.drag')
const target = document.querySelector('.target')
target.addEventListener('dragenter', ondragenter)
target.addEventListener('dragover', ondragover)
target.addEventListener('dragleave', ondragleave)
target.addEventListener('drop', ondrop)
function ondragenter(event) {
console.log('进入入其容器范围内触发')
}
function ondragover(event) {
event.preventDefault()
console.log('容器中拖动时触发')
}
function ondragleave(event) {
console.log('离开目标容器时触发')
}
function ondrop(event) {
console.log('释放鼠标时触发')
}
</script>
Data Transfer
When performing a drag-and-drop operation, the dataTransfer object can be used to save the dragged data. It can save one or more data, one or most data types. To put it simply, it can be used to transmit the dragged data so that other operations can be performed on the data when the drag is completed.
- setData(type, data): used to declare the data sent
- getData(type): used to obtain data of a specified type . Note: it can only be obtained in ondrop.
- clearData(type): used to clear data of a specified type
<div id="app">
<div class="drag" draggable="true"></div>
<div class="target"></div>
</div>
<script>
const drag = document.querySelector('.drag')
const target = document.querySelector('.target')
drag.addEventListener('dragstart', dragstart)
target.addEventListener('dragover', ondragover)
target.addEventListener('drop', ondrop)
function dragstart(event) {
event.dataTransfer.setData('comp', JSON.stringify({name: 'WFT'}))
}
function ondragover(event) {
event.preventDefault()
}
function ondrop(event) {
let data = JSON.parse(event.dataTransfer.getData('comp'))
console.log(data)
// ...
// 处理完数据 最后清除一下
event.dataTransfer.clearData()
}
</script>
In other events (such as ondragover
, ondragleave
etc.), the value in dataTransfer cannot be obtained. This is due to W3C's requirement to protect the values in dataTransfer [ Reference ]. Therefore, if you need to obtain data in these events, you can only achieve it through a global variable or other methods.
event.dataTransfer.setDragImage(p_w_picpath, x, y)
The setDragImage method is used to modify the image pointed by the mouse pointer during the drag and drop operation.
Example one:
Let’s look at the effect first:
First of all, this is different from dragging an element with the mouse and keeping moving with the mouse. The three core mouse events used are onmousedown, onmousemove, and onmouseup. Ours is dragging, which means it is in a motionless state.
Here is the complete code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="drag" draggable="true"></div>
<div class="target"></div>
</div>
<script>
const drag = document.querySelector('.drag')
const target = document.querySelector('.target')
drag.addEventListener('dragstart', dragstart)
target.addEventListener('dragover', ondragover)
target.addEventListener('drop', ondrop)
let curDragDom = null
let curOffsetX = 0
let curOffsetY = 0
// 开始拖拽
function dragstart(event) {
curDragDom = this
curOffsetX = event.offsetX
curOffsetY = event.offsetY
}
// 在目标元素中拖拽 移除掉默认事件 否则不会触发 drop事件
function ondragover(event) {
event.preventDefault()
}
// 在目标容器中松开鼠标
function ondrop(event) {
if(!curDragDom) return
let copyDom = curDragDom.cloneNode(true)
copyDom.style.position = 'absolute'
const { x, y } = this.getBoundingClientRect()
copyDom.style.left = event.clientX - x - curOffsetX + 'px'
copyDom.style.top = event.clientY - y - curOffsetY + 'px'
copyDom.removeAttribute('draggable')
this.appendChild(copyDom)
}
</script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#app {
width: 100vw;
height: 100vh;
padding: 50px 0 0 50px;
box-sizing: border-box;
display: flex;
}
.drag {
width: 100px;
height: 100px;
background-color: red;
}
.target {
width: 400px;
height: 400px;
border: 1px solid red;
margin-left: 200px;
position: relative;
overflow: hidden;
}
</style>
</body>
</html>
Example two:
Complete code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="upload" draggable="true">
<div>将文件拖到此处进行上传</div>
</div>
<div class="images"></div>
</div>
<script>
const upload = document.querySelector('.upload')
const imageContainer = document.querySelector('.images')
upload.addEventListener('dragover', ondragover)
upload.addEventListener('drop', ondrop)
function ondragover(event) {
event.preventDefault()
}
function ondrop(event) {
event.preventDefault()
const { files } = event.dataTransfer
Array.from(files).forEach(blob => {
const url = window.URL.createObjectURL(new Blob([blob]))
const img = document.createElement('img')
img.src = url
imageContainer.appendChild(img)
})
}
</script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#app {
width: 100vw;
height: 100vh;
padding: 50px 0 0 50px;
box-sizing: border-box;
}
.upload {
width: 360px;
height: 180px;
border: 1px dashed #c0c4cc;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
}
.upload > div {
color: #606266;
font-size: 14px;
}
.images {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 10px;
}
.images img {
width: 300px;
height: 180px;
margin-right: 20px;
}
</style>
</body>
</html>