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

效果

源码

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);
    });
});
相关推荐
七号练习生.c4 分钟前
JavaScript基础入门
开发语言·javascript·ecmascript
常常不爱学习5 分钟前
Vue3 + TypeScript学习
开发语言·css·学习·typescript·html
黄毛火烧雪下17 分钟前
React Native (RN)项目在web、Android和IOS上运行
android·前端·react native
fruge23 分钟前
前端正则表达式实战合集:表单验证与字符串处理高频场景
前端·正则表达式
baozj27 分钟前
🚀 手动改 500 个文件?不存在的!我用 AST 撸了个 Vue 国际化神器
前端·javascript·vue.js
用户40993225021236 分钟前
为什么Vue 3的计算属性能解决模板臃肿、性能优化和双向同步三大痛点?
前端·ai编程·trae
海云前端137 分钟前
Vue首屏加速秘籍 组件按需加载真能省一半时间
前端
蛋仔聊测试38 分钟前
Playwright 中route 方法模拟测试数据(Mocking)详解
前端·python·测试
零号机1 小时前
使用TRAE 30分钟极速开发一款划词中英互译浏览器插件
前端·人工智能
molly cheung1 小时前
FetchAPI 请求流式数据 基本用法
javascript·fetch·请求取消·流式·流式数据·流式请求取消