前端基础(四十):拖放功能的实现

效果

源码

html 复制代码
<div class="draggable-wrap">
    <div class="draggable-box" draggable="true" data-json='{"name": "Lee"}'>
        <h1>Lee</h1>
        <div class="drop-box" data-json='{"name": "Lee"}'>
            <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
                <path d="M639.996 1023.988H384.002l42.656-512.582h170.684z" fill="#ED5564"></path>
                <path
                    d="M939.552 310.66l-295.43-42.936L512 0.012l-132.124 267.712L84.448 310.66l213.774 208.402-50.466 294.242L512 674.372l264.244 138.932-50.468-294.242z"
                    fill="#FFCE54"></path>
                <path d="M939.552 310.66L512 469.312l213.776 49.75z" fill="#F6BB42"></path>
                <path
                    d="M512 874.648c-11.782 0-21.344 9.562-21.344 21.344v127.996h42.686v-127.996c0-11.782-9.562-21.344-21.342-21.344z"
                    fill="#DA4453"></path>
                <path
                    d="M512 469.312v205.06l264.244 138.932zM298.222 519.062l-50.466 294.242L512 469.312zM379.876 267.724L84.448 310.66 512 469.312zM512 0.012v469.3l132.122-201.588z"
                    fill="#F6BB42"></path>
            </svg>
        </div>
    </div>
    <div class="draggable-box" draggable="true" data-json='{"name": "Tom"}'>
        <h1>Tom</h1>
        <div class="drop-box" data-json='{"name": "Tom"}'>
            <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
                <path d="M639.996 1023.988H384.002l42.656-512.582h170.684z" fill="#ED5564"></path>
                <path
                    d="M939.552 310.66l-295.43-42.936L512 0.012l-132.124 267.712L84.448 310.66l213.774 208.402-50.466 294.242L512 674.372l264.244 138.932-50.468-294.242z"
                    fill="#FFCE54"></path>
                <path d="M939.552 310.66L512 469.312l213.776 49.75z" fill="#F6BB42"></path>
                <path
                    d="M512 874.648c-11.782 0-21.344 9.562-21.344 21.344v127.996h42.686v-127.996c0-11.782-9.562-21.344-21.342-21.344z"
                    fill="#DA4453"></path>
                <path
                    d="M512 469.312v205.06l264.244 138.932zM298.222 519.062l-50.466 294.242L512 469.312zM379.876 267.724L84.448 310.66 512 469.312zM512 0.012v469.3l132.122-201.588z"
                    fill="#F6BB42"></path>
            </svg>
        </div>
    </div>
    <div class="draggable-box" draggable="true" data-json='{"name": "Jerry"}'>
        <h1>Jerry</h1>
        <div class="drop-box" data-json='{"name": "Jerry"}'>
            <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
                <path d="M639.996 1023.988H384.002l42.656-512.582h170.684z" fill="#ED5564"></path>
                <path
                    d="M939.552 310.66l-295.43-42.936L512 0.012l-132.124 267.712L84.448 310.66l213.774 208.402-50.466 294.242L512 674.372l264.244 138.932-50.468-294.242z"
                    fill="#FFCE54"></path>
                <path d="M939.552 310.66L512 469.312l213.776 49.75z" fill="#F6BB42"></path>
                <path
                    d="M512 874.648c-11.782 0-21.344 9.562-21.344 21.344v127.996h42.686v-127.996c0-11.782-9.562-21.344-21.342-21.344z"
                    fill="#DA4453"></path>
                <path
                    d="M512 469.312v205.06l264.244 138.932zM298.222 519.062l-50.466 294.242L512 469.312zM379.876 267.724L84.448 310.66 512 469.312zM512 0.012v469.3l132.122-201.588z"
                    fill="#F6BB42"></path>
            </svg>
        </div>
    </div>
</div>
css 复制代码
body {
    margin: 0;
    user-select: none;
}

.draggable-wrap {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 80px;

    .draggable-box {
        position: relative;
        width: 240px;
        height: 140px;
        border: 3px solid black;
        scale: 1.2;

        h1 {
            text-align: center;
        }

        &:nth-child(1) {
            background-color: red;
        }

        &:nth-child(2) {
            background-color: green;
        }

        &:nth-child(3) {
            background-color: blue;
        }

        &[drag="start"] {
            opacity: .2;
        }

        &[drag="end"] {
            opacity: 1;
        }

        .drop-box {
            opacity: 0;
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            border: 3px dashed black;
            background-color: rgba(0, 0, 0, .5);
            transition: 1s;
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;

            .icon {
                display: none;
                width: 80px;
                height: 80px;
            }

            &[drag="enter"] {
                opacity: 1;

                &::after {
                    content: '';
                    display: block;
                    position: absolute;
                    top: 0;
                    right: 0;
                    bottom: 0;
                    left: 0;
                }

                .icon {
                    display: block;
                }
            }


            &[drag="leave"] {
                opacity: 0;

                .icon {
                    display: none;
                }
            }


            &[drag="drop"] {
                opacity: 1;

                .icon {
                    display: block;
                }
            }
        }
    }
}
js 复制代码
const draggables = document.querySelectorAll('.draggable-box');
const drops = document.querySelectorAll('.drop-box');

draggables.forEach(el => {
    el.addEventListener('dragstart', e => {
        e.target.setAttribute('drag', 'start');
        e.dataTransfer.setData('data', e.target.getAttribute('data-json'));
    });
    el.addEventListener('dragend', e => {
        e.target.setAttribute('drag', 'end');
    });
});

drops.forEach(el => {
    el.addEventListener('dragenter', e => {
        e.stopPropagation();
        e.target.setAttribute('drag', 'enter');
    });
    el.addEventListener('dragover', e => e.preventDefault());
    el.addEventListener('dragleave', e => {
        e.stopPropagation();
        e.target.setAttribute('drag', 'leave');
    });
    el.addEventListener('drop', e => {
        e.target.setAttribute('drag', 'drop');
        const source = JSON.parse(e.dataTransfer.getData('data'));
        const target = JSON.parse(e.target.getAttribute('data-json'));
        console.log(source, target);
    });
});
相关推荐
jinanwuhuaguo11 小时前
(第二十九篇)OpenClaw 实时与具身的跃迁——从异步孤岛到数字世界的“原住民”
前端·网络·人工智能·重构·openclaw
广州华水科技11 小时前
深度测评2026年单北斗GNSS位移监测系统推荐,与高口碑变形监测设备一同引领行业新风尚
前端
Alice-YUE12 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
是上好佳佳佳呀13 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
莎士比亚的文学花园14 小时前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
CDN36014 小时前
排查实录:网站偶发502/504错误?360CDN回源超时配置与日志分析技巧
前端·数据库
之歆14 小时前
Day07_CSS盒子模型 · 样式继承 · 用户代理样式
前端·css
01漫游者14 小时前
JavaScript函数与对象增强知识
开发语言·javascript·ecmascript
DanCheOo15 小时前
AI 应用的安全架构:Prompt 注入、数据泄露、权限边界
前端·人工智能·prompt·安全架构
We་ct16 小时前
深度剖析浏览器跨域问题
开发语言·前端·浏览器·跨域·cors·同源·浏览器跨域