基于拖拽库 dragula 实现的前端可视化代码生成 demo

参考

说明

还有很多问题待优化,仅供参考。

环境

依赖库 版本 操作
dragula.min.js 3.7.3 下载
dragula.min.css 3.7.3 下载

演示效果

image

代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="dragula.min.css">
    <style>
        *{
            font-size: 30px;
        }
        #con {
            margin: 0 auto;
            min-height: 500px;
            background-color: #CCC;
        }

        .list {}

        .xiaqiuchu1 li {
            width: 500px;
            height: 200px;
            margin-top: 50px;
            background-color: rgb(90, 188, 116);
            display: inline-block;

        }

        .xiaqiuchu2 li {
            width: 500px;
            height: 200px;
            margin-top: 50px;
            background-color: red;
            display: inline-block;
        }

        .test-con {
            min-height: 200px;
            background-color: yellow;
        }

        .template {
            display: none;
        }
    </style>
</head>

<body>
    <h1>栅格拖拽只需要把栅格里面的元素设置为允许拖拽入即可,但是禁止拖拽出</h1>
    <h1>当前配置栅格可用,直接给页面最顶层设置一个绑定,栅格作为顶层下的,然后栅格内的可以拖拽即可</h1>
    <div id="buttons">
        <button data-type="line-input">单行文本框</button>
        <button data-type="lines-input">多行文本框</button>
    </div>
    <div id="con">
        容器
        <div class="test-con container">
            节点
        </div>
        <ul class="xiaqiuchu1 container">
            <li class="container">节点</li>
            <li>节点</li>
        </ul>
        <ul class="xiaqiuchu2 container">
            <li>容器</li>
            <li>节点</li>
        </ul>
    </div>

    <!-- 模板列表 -->
    <div id="line-input" class="template">
        <input type="text">
    </div>
    <div id="lines-input" class="template">
        <textarea name="" id="" cols="30" rows="10"></textarea>
    </div>
    <script src="dragula.min.js"></script>
    <script>
	// list数组可以动态追加,并且新追加的元素也会参与拖拽行为
        const list = [
            document.querySelector("#buttons"),
            document.querySelector("#con"),
            document.querySelector(".xiaqiuchu2 li"),
        ];
        const d = dragula(list, {
            // 如果是这个buttons元素下的,就可以被复制(不是移动)
            copy: function (el, source) {
                return source === document.getElementById("buttons")
            },
            // 移动处理
            moves: function (el, source, handle, sibling) {
                // console.log(el, source, handle, sibling);
                if (source == document.querySelector(".xiaqiuchu2")) {
                    return false;
                }
                return true; // elements are always draggable by default
            },
            // 传入节点的时候如果父元素是buttons,就不接受传入
            accepts: function (el, target) {
                // xiaqiuchu2 禁止传入,但是自己的孩子支持传入(也就是栅格)
                if (target == document.querySelector(".xiaqiuchu2")) {
                    return false;
                }
                // 禁止拖拽到butons的是禁止的
                if (target == document.getElementById("buttons")) {
                    return false;
                }
                return true;
            },
            invalid: function (el, handle) {
                return false; // 默认情况下不会阻止任何拖动
            },
            direction: 'horizontal',             //元素的排放方向
            //   copy: false,                       // 拖动的元素是否为副本
            //   copySortSource: false,             // 复制的源容器重新排序
            //   revertOnSpill: false,              // 是否将拖到容器外的元素放回原处
            // removeOnSpill: true,              // 是否将拖到容器外的元素删除
            //   mirrorContainer: document.body,    // 设置获取附加镜像元素的元素
            //   ignoreInputTextSelection: true     //允许用户选择输入文本
        });
        /**
         * 监听执行完毕后替换元素
         * */
        d.on('drop', function (el, target, source, sibling) {
            // 替换元素
            const idKey = el.dataset.type;
            const template = document.getElementById(idKey);
            // 如果找不到元素就不执行操作
            if (template == null) {
                return;
            }
            target.replaceChild(template.children[0].cloneNode(), el);
        });
    </script>
</body>

</html>
posted @ 2022-07-31 10:39  夏秋初  阅读(601)  评论(0编辑  收藏  举报