拖放API快速上手

9/21/2022 JavaScriptAPI

# HTML拖放API快速上手

最近在写一个网页拖放的小东西,一开始是以为要监听鼠标的点击移动和释放事件,后来查询发现不用那么麻烦,浏览器提供了内置的Drag 和 Drop API

# Grag & Drop

# 工作原理

给需要拖拽的元素添加以下代码:

 <div
      draggable="true"
      ondrag="handleDrag"
  />

可放置区域(即接受拖拽元素的元素)

<div
     ondragover="handleGragover"
     ondrop="handleDrop"
 />

// 同时阻止默认的点击事件
// 原因:浏览器对默认的拖拽事件是禁止的
e.preventDefault()

# ondrag

拖拽开始

可存放拖拽数据,例如元素ID

# ondragover

进入放置区域

可进行更改样式等操作

# ondrop

元素放置时

对拖拽元素进行真实的移动

# Demo

实现一个简单的页面文件和元素的拖拽

# 实现效果

  • 对于元素

  • 对于图片

DragImg

# 代码实现

  • HTML

        <main>
            <div class="draggable-container">
                <div id="draggable" class="draggable" draggable="true"></div>
            </div>
            <div id="droppable" class="droppable"></div>
        </main>
    
  • CSS

    *{
        box-sizing: border-box;
        padding: 0;
        margin: 0;
    }
    main{
        width: 100vw;
        height: 100vh;
        display: grid;
        grid-template-columns: 1fr 1fr;
        place-items: center;
        background-color: hsl(0deg, 0%, 10%);
    }
    .draggable-container {
        width: 100%;
        height: 100%;
        display: grid;
        place-items: center;
    }
    
    .draggable,
    .droppable {
        border-radius: 4px;
    }
    
    .draggable {
        width: 25vw;
        height: 25vw;
        background-color: #00d9ff;
    }
    
    
    .droppable {
        width: 30vw;
        height: 30vw;
        border: 8px dashed #00d9ff;
        position: relative;
        display: grid;
        place-items: center;
    }
    
    .droppable::before {
        display: block;
        content: "请拖放到此区域";
        position: absolute;
        color: white;
        font-family: sans-serif;
        font-size: 3vw;
        color: hsl(0, 0%, 30%);
    }
    
    .droppable img {
        width: 80%;
        height: 80%;
        object-fit: contain;
    }
    
    .dragover {
        border: 8px dashed #ffae00;
    }
    .dropped {
        border: 8px dashed #48ff00;
    }
    .dropped::before {
        z-index: -1;
    }
    
  • JS

            const draggable = document.getElementById('draggable');
            const droppable = document.getElementById('droppable');
    
            draggable.addEventListener('dragstart', handleDragStart);
            droppable.addEventListener('dragover', handleDragover);
            droppable.addEventListener('dragleave', handleDragLeave);
            droppable.addEventListener('drop', handleDrop);
    
    
            function handleDragStart(e) {
                e.dataTransfer.setData('text/plain', e.target.id)
            }
    
            function handleDragover(e) {
                e.preventDefault();
                droppable.classList.add('dragover');
            }
    
            function handleDragLeave(e) {
                droppable.classList.remove('dragover')
            }
    
            function handleDrop(e) {
                e.preventDefault();
                
                // 如果是文件
                [ ...e.dataTransfer.items].forEach((item)=>{
                    if (item.kind === "file") {
                        const file = item.getAsFile();
                        createPreview(file);
                    }
                })
    
                // 如果是元素
                const draggedid = e.dataTransfer.getData("text/plain");
                droppable.appendChild(document.getElementById(draggedid));
                droppable.classList.add('dropped');
            }
    
            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);
                }
                droppable.appendChild(image);
    
            }
    
斑驳陆离之林,恍若隔世
Robyn