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

文章作者: Damao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Damao !
  目录