js拖拽事件实现简单选课功能

发布于:2025-05-23 ⋅ 阅读:(23) ⋅ 点赞:(0)

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html, body {
            width: 100%;
            height: 100%;
            min-width: 1100px;
            background-color: rgb(87, 202, 11);
        }
        .content {
            border-radius: 5px;
            color: #fff;
            font-weight: bolder;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            padding: 30px 50px;
        }
        .list {
            width: 130px;
            flex: none;
            background: rgb(212, 195, 109);
            border-radius: 10px;
            margin-right: 20px;
            padding: 10px 0;
        }
        .item {
            background-color: cornflowerblue;
            width: 80px;
            height: 45px;
            line-height: 45px;
            color: #fff;
            font-size: 18px;
            font-weight: bolder;
            border-radius: 10px;
            text-align: center;
            cursor: pointer;
            margin: 10px auto;
        }
        .courses-box {
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: antiquewhite;
            border-radius: 10px;
            flex: none;
            width: 900px;
            height: 600px;
            box-sizing: border-box;
            padding: 30px;
        }
        .time-box {
            width: 30px;
            flex: none;
            margin-right: 30px;
            padding-top: 30px;
        }
        .time {
            width: 30px;
            height: 200px;
            background-color: rgb(10, 164, 112);
            border-radius: 10px;
            margin-top: 15px;
            /* 文字排列方向 */
            writing-mode: vertical-lr;
            text-align: center;
            letter-spacing: 10px;
            padding-left: 3px;
        }
        .day-box {
            flex: 1;
            height: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            border-radius: 10px;
        }
        .day {
            width: 100%;
            flex: none;
            display: flex;
            align-items: center;
            justify-content: space-around;
        }
        .day span {
            width: 80px;
            height: 35px;
            line-height: 35px;
            margin-bottom: 10px;
            background-color: rgb(10, 164, 112);
            border-radius: 5px;
            text-align: center;
        }
        .courses {
            flex: 1;
            width: 100%;
            background-color: rgb(10, 164, 112);
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: space-around;
            padding: 10px;
        }
        .course-box {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: space-around;
        }
        .course {
            width: 90px;
            height: 50px;
            background-color: beige;
            margin: 5px 0;
            border-radius: 5px;
            display: flex;
            align-items: center;
        }
        .course:nth-child(4) {
            margin-bottom: 15px;
        }
        .drag-over {
            background-color: rgb(159, 69, 69);
        }
    </style>
</head>
<body>
    <div class="content">
        <div class="list" data-allowed="move">
        	<!-- draggable为true元素才能拖拽 -->
            <div class="item" draggable="true" data-effect="copy">语文</div>
            <div class="item" draggable="true" data-effect="copy">数学</div>
            <div class="item" draggable="true" data-effect="copy">英语</div>
            <div class="item" draggable="true" data-effect="copy">科学</div>
            <div class="item" draggable="true" data-effect="copy">体育</div>
            <div class="item" draggable="true" data-effect="copy">地理</div>
            <div class="item" draggable="true" data-effect="copy">历史</div>
            <div class="item" draggable="true" data-effect="copy">物理</div>
        </div>
        <div class="courses-box">
            <div class="time-box">
                <div class="time">上午</div>
                <div class="time">下午</div>
            </div>
            <div class="day-box">
                <div class="day">
                    <span>星期一</span>
                    <span>星期二</span>
                    <span>星期三</span>
                    <span>星期四</span>
                    <span>星期五</span>
                    <span>星期六</span>
                    <span>星期日</span>
                </div>
                <div class="courses"></div>
            </div>
        </div>
    </div>
    <script src="./drag.js"></script>
</body>
</html>

js

const content = document.querySelector('.content');
const coursesDom = document.querySelector('.courses');
const courses = new Array(7).fill({
    morning: new Array(4).fill(''),
    afternoon: new Array(4).fill(''),
})

const renderCourses = () => {
    courses.forEach((dayCourse) => {
        const { morning, afternoon } = dayCourse;
        const div = document.createElement('div');
        div.classList.add('course-box');
        [...morning, ...afternoon].forEach((course) => {
            const span = document.createElement('span');
            span.textContent = course;
            span.classList.add('course');
            span.dataset.allowed = 'copy';
            div.appendChild(span);
        });
        coursesDom.appendChild(div);
    });
}

renderCourses();

const clearStyle = () => {
    const doms = document.querySelectorAll('.drag-over');
    doms.forEach((dom) => {
        dom.classList.remove('drag-over');
    });
}

// 当前在拖拽的元素变量
let source = null;
content.ondragstart = (e) => {
    // e.target为当前拖拽的元素
    console.log('srart', e.target);
    // 改变鼠标样式为copy样式,为一个加号
    e.dataTransfer.effectAllowed = e.target.dataset.effect;  // 取值:move、copy等
    source = e.target;
};

content.ondragover = function(e) {
    e.preventDefault();
    // e.target为当前停留的元素,不停触发
    console.log('over', e.target);
};

const findParentNode = (node) => {
    while(node) {
        if (node.dataset && node.dataset.allowed) {
            return node;
        }
        node = node.parentNode;
    }
}

content.ondragenter = (e) => {
    e.preventDefault();
    // e.target为当前进入的元素
    console.log('enter', e.target);
    clearStyle();
    const node = findParentNode(e.target);
    if (!node) {
        return;
    }
    if (source.dataset.effect === node.dataset.allowed) {
        e.target.classList.add('drag-over');
    }
};

content.ondragleave = (e) => {
    // e.target为当前离开的元素
    console.log('leave', e.target);
};

content.ondrop = (e) => {
    clearStyle();
    // e.target松开鼠标时所在的元素,这个方法能被触发,要确保ondragover中 e.preventDefault();因为元素默认是不允许其他元素拖到上面的
    console.log('drop', e.target);
    if (source.dataset.effect === e.target.dataset.allowed) {
        if (source.dataset.effect === 'copy') {
            e.target.innerHTML = '';
            const dom  = source.cloneNode(true);
            dom.dataset.effect = 'move';
            e.target.appendChild(dom);
        } else {
            // 清空所有子元素
            source.remove();
        }
    }
};

效果图
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到