HTML拖拽API


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 元素的拖拽,一般需要以下几个步骤:

    1. 给想要拖拽的元素设置 draggable 属性为 true
    2. 设置拖拽监听事件来完成自己的需求
    3. 若有需要,在监听事件中设置拖拽数据

示例

<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)
}

  目录