HTML拖拽API备忘清单
事件 | on事件处理程序 | 触发时刻 |
---|---|---|
drag | ondrag | 当拖拽元素或选中的文本时触发 |
dragend | ondragend | 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键) |
dragenter | ondragenter | 当拖拽元素或选中的文本到一个可释放目标时触发 |
dragexit | ondragexit | 当元素变得不再是拖拽操作的选中目标时触发 |
dragleave | ondragleave | 当拖拽元素或选中的文本离开一个可释放目标时触发 |
dragover | ondragover | 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次) |
dragstart | ondragstart | 当用户开始拖拽一个元素或选中的文本时触发 |
drop | ondrop | 当元素或选中的文本在可释放目标上被释放时触发 |
使用
在拖拽过程中,可以使用 DataTransfer, DataTransferItem 和DataTransferItemList 来传输与拖拽元素绑定的数据。
因此实现一个 HTML 元素的拖拽,一般需要以下几个步骤:
- 给想要拖拽的元素设置 draggable 属性为 true
- 设置拖拽监听事件来完成自己的需求
- 若有需要,在监听事件中设置拖拽数据
示例
<div className="html-drag-container">
<div id="html-drag-box-container">
<div class="html-drag-box" draggable="true"></div>
</div>
<div id="html-drag-img-container">
<img class="html-drag-img" src="https://dummyimage.com/600x400/ffd53b/fff.png&text=photo"></img>
</div>
<div class="html-drop-box"></div>
<button id="reset-btn">reset</button>
</div>
.html-drag-container {
height: 70vh;
background-color: #eee;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
justify-items: center;
align-items: center;
}
#html-drag-box-container {
grid-row: 2 / 3;
grid-column: 1/ 2;
}
.html-drag-box {
width: 10vw;
height: 12vh;
background-color: tomato;
border-radius: 10px;
position: relative;
}
#html-drag-img-container {
grid-row: 2 / 3;
grid-column: 3/ 4;
}
.html-drag-img {
width: 10vw;
height: 12vh;
border-radius: 10px;
position: relative;
}
.html-drop-box {
grid-row: 2 / 3;
grid-column: 2/ 3;
border: rgb(20, 179, 241) dashed 4px;
border-radius: 10px;
width: 14vw;
height: 18vh;
display: flex;
justify-content: center;
align-items: center;
}
.html-drop-box::before {
display: block;
content: "请拖放到此区域";
position: absolute;
color: rgb(160, 157, 157);
font-family: sans-serif;
font-size: 2vh;
}
.html-dropped {
border-color: rgb(17, 241, 28);
}
.html-dropover {
border-color: rgb(252, 83, 32);
}
/* 用于限制从本地拖入图片时的大小 */
.html-drop-box img {
width: 10vw;
height: 12vh;
position: relative ;
}
let dragbox = document.getElementsByClassName('html-drag-box')[0];
let dropbox = document.getElementsByClassName('html-drop-box')[0];
let dragimg = document.getElementsByClassName('html-drag-img')[0];
let boxcontainer = document.getElementById('html-drag-box-container');
let imgcontainer = document.getElementById('html-drag-img-container');
let resetBtn = document.getElementById('reset-btn');
dragbox.addEventListener('dragstart', onDragStart);
dragbox.addEventListener('dragend', onDragEnd);
dragimg.addEventListener('dragstart', onDragStart);
dragimg.addEventListener('dragend', onDragEnd);
dropbox.addEventListener('dragover', onDragOver);
dropbox.addEventListener('dragleave', onDragLeave);
dropbox.addEventListener('drop', onDrop);
resetBtn.addEventListener('click', resetElement);
function onDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.className);
e.target.style.opacity = .7;
}
function onDragEnd(e) {
e.target.style.opacity = "";
}
function onDragOver(e) {
// 默认情况下是不允许放置拖拽元素的,因此需要取消默认设置
e.preventDefault();
dropbox.classList.add('html-dropover');
}
function onDragLeave(e) {
dropbox.classList.remove('html-dropover');
}
function onDrop(e) {
// 阻止一些默认操作,如拖拽超链接会默认打开页面
e.preventDefault();
resetElement();
dropbox.classList.remove('html-dropover');
dropbox.classList.add('html-dropped');
let isFile = false;
// 若拖拽对象是文件
[...e.dataTransfer.items].forEach((item) => {
if (item.kind === "file") {
const file = item.getAsFile();
createPreview(file);
isFile = true;
}
});
if (isFile) return;
dropbox.appendChild(document.getElementsByClassName(e.dataTransfer.getData('text/plain'))[0]);
}
function createPreview(imageFile) {
if (!imageFile.type.startsWith("image/")) {
return;
}
const image = document.createElement("img");
image.src = URL.createObjectURL(imageFile);
image.onload = function () {
URL.revokeObjectURL(this.src);
};
dropbox.appendChild(image);
}
function resetElement() {
if (dropbox.classList.contains('html-dropped')) {
dropbox.classList.remove('html-dropped')
}
boxcontainer.appendChild(dragbox);
imgcontainer.appendChild(dragimg)
}