[笔记]JavaScript 实现按钮拖拽效果

原文链接
魔改了下大佬的代码。

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title>拖动</title>
    <style>
        h2 {
            font-size: 20px;
            color: #0d88c1;
        }

        div#left,
        div#right {
            width: 120px;
            float: left;
            margin: 10px 100px 10px 0px;
            height: 240px;
            background-color: #dddddd;
            overflow-y: auto;
        }

        div label {
            font-size: 22px;
            font-weight: bold;
            width: 100%;
            display: inline-block;
            padding: 4px 0;
            text-align: center;
            margin: 0px 0 2px 0;
            color: #fff;
            background-color: #0d88c1;
        }

        .over {
            border: 1px dashed red;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <h2>拖放(Drag 和 drop)</h2>
    <!-- 左边元素框 -->
    <div id="left" class="drag-container1">
        <label draggable="true" class>index1</label>
        <label draggable="true" class>index2</label>
        <label draggable="true" class>index3</label>
        <label draggable="true" class>index4</label>
        <label draggable="true" class>index5</label>
        <label draggable="true" class>index6</label>
        <label draggable="true" class>index7</label>
    </div>
    <!-- 右边元素框 -->
    <div id="right" class="drag-container1"></div>
    <script>
        (async () => {
            let container1DragElement = null;
            const containerName = "drag-container1";
            // 获取元素 selector
            function getSelector(el) {
                var tag, index = 1, stack = [];
                for (; el.parentNode; el = el.parentNode) {
                    tag = el.tagName;
                    if (tag != "HTML") {
                        for (child of el.parentNode.children) {
                            if (child == el) {
                                break;
                            } else {
                                index++;
                            }
                        }
                        if (tag == "BODY") {
                            stack.unshift(tag);
                        } else {
                            stack.unshift(tag + ':nth-child(' + index + ')');
                        }
                    }
                }
                return stack.join(' > ');
            }
            /**
            * 判断是否是容器
            */
            function isContainer(ele) {
                return ele && ele.classList.contains(containerName);
            }
            function findContainer(ele) {
                var container = ele;
                while (true) {
                    if (container.tagName == "HTML") {
                        return isContainer(container);
                    }
                    if (container.classList.contains(containerName)) {
                        return container;
                    }
                    container = container.parentNode;
                }
                return container;
            }
            var moveItem = document.getElementsByTagName('label');
            for (let i = 0; i < moveItem.length; i++) {
                //动态设置label元素id
                moveItem[i].setAttribute('id', 'label' + i);
                moveItem[i].ondragstart = function (ev) {
                    //dataTransfer.setData() 方法设置被拖数据的数据类型和值
                    container1DragElement = this;
                    { {/*  ev.dataTransfer.setData("dragElementSelector", getSelector(this));  */ } }
                    ev.dataTransfer.setData("offsetX", getSelector(ev.offsetX));
                    ev.dataTransfer.setData("offsetY", getSelector(ev.offsetY));
                };
            }
            const containers = document.querySelectorAll(".drag-container1");
            containers.forEach(container => {
                // 阻止向上冒泡
                container.ondragover = ev => ev.preventDefault();
                container.ondragenter = ev => ev.target.classList.add('over');
                container.ondragleave = ev => ev.target.classList.remove('over');
                container.ondrop = function (ev) {
                    ev.preventDefault();
                    ev.target.classList.remove('over');
                    let container = null;
                    if (isContainer(ev.toElement)) {
                        //如果为container,元素放置在末尾
                        container = ev.toElement;
                        container.appendChild(container1DragElement);
                    } else {
                        container = findContainer(ev.toElement);
                        if (!container) {
                            console.warn("没有找到目标容器,无法执行拖拽操作");
                            return;
                        }
                        if (ev.toElement.nextElementSibling) {
                            console.log("ev.toElement.nextElementSibling", ev.toElement.nextElementSibling);
                            console.log("container1DragElement", container1DragElement);
                            if (ev.toElement.nextElementSibling == container1DragElement) {
                                // 如果是两个相邻的标签,则交换这两个标签
                                container.insertBefore(ev.toElement.nextElementSibling, ev.toElement);
                            } else {
                                container.insertBefore(container1DragElement, ev.toElement.nextElementSibling);
                            }
                        } else {
                            container.appendChild(container1DragElement);
                        }

                    }
                }
            });
        })();
    </script>
</body>

</html>
···


### 参考资料
[JavaScript进阶之实现拖拽(上)](https://juejin.cn/post/6844904158273765384)
[https://www.nhooo.com/note/qadmbg.html](https://www.nhooo.com/note/qadmbg.html)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值