使用Sortable.js,ul嵌套3层,树形结构,有个问题是能拖拽出自己当前的容器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Sortable.js,ul嵌套3层,树形结构,有个问题是能拖拽出自己当前的容器相关的知识,希望对你有一定的参考价值。

想要的效果是平级可以拖拽排序,但是有个问题是总能越级拖拽出自己的容器,和本来的容器平级。

参考技术A 重新完善一下 刚才没看清你的问题 获取拖拽后 鼠标的坐标 获取父元素在屏幕上四边的坐标 if判断一下 超出了就阻止事件冒泡

EasyUI之树形菜单

EasyUI是用ul和li标签来完成树形结构的组合的,一个ul可视为父节点,li作为树形结构的子节点,而li标签里面嵌套的ul标签又可以作为父节点,不断的重复从而达到完成复杂树形结构的功能。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 必须引用的css文件 -->
<link rel="stylesheet" href="/static/js/easyui/themes/default.css"/>
<link rel="stylesheet" href="/static/css/module.css"/>

<!-- 引入公用js文件 -->
<script type="text/javascript" src="/static/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/easyui/jquery.easyui.min.js"></script> 
<title>easyui tree的使用</title>
</head>
<body>
    <ul class="easyui-tree">
        <li><span>红楼梦</span>
            <ul>
                <li>第1回  甄士隐梦幻识通灵   贾雨村风尘怀闺秀</li>
                <li>第2回  贾夫人仙逝扬州城   冷子兴演说荣国府</li>
                <li>第3回  托内兄如海荐西宾   接外孙贾母惜孤女</li>
                <li>第4回  薄命女偏逢薄命郎   葫芦僧判断葫芦案</li>
                <li>第5回  贾宝玉神游太虚境   警幻仙曲演红楼梦</li>
            </ul>
        </li>
        <li><span>水浒传</span></li>
        <li><span>三国演义</span>
            <ul>
                <li>第001回  宴桃园豪杰三结义 斩黄巾英雄首立功</li>
                <li>第002回 张翼德怒鞭督邮 何国舅谋诛宦竖</li>
                <li>第003回 议温明董卓叱丁原 馈金珠李肃说吕布</li>
                <li>第004回 废汉帝陈留践位 谋董贼孟德献刀</li>
                <li>第005回 发矫诏诸镇应曹公 破关兵三英战吕布</li>
            </ul>
        </li>
        <li><span>西游记</span></li>
    </ul>
</body>
</html>

技术分享图片
这是一个最简单的树形结构图,你可以自由的修改嵌套的ul,li。下面的案例将展示如果从远程加载树形结构的节点。

<body>
    <ul class="easyui-tree" id="tree" url="tree_data.json">
    </ul>
</body>

这里我省略掉了head标签头部的内容,因为这里面的内容和前一个案例一模一样的,本案例并没有额外的添加css,js文件和额外的js代码。你只需要加上你的url地址就行了,你的json数据定义应类似于:

[
    {
        "id":"1",
        "text":"北京",
        "children":[
            {
                "id":"2",
                "text":"朝阳"
            },{
                "id":"6",
                "text":"东城",
                "children":[
                    {
                        "id":"8",
                        "text":"王府井"
                    },{
                        "id":"9",
                        "text":"西单"
                    }
                ]
            },{
                "id":"7",
                "text":"西城"
            }
        ]
    },{
        "id":"3",
        "text":"天津"
    },{
        "id":"4",
        "text":"上海" 
    },{
        "id":"5",
        "text":"深圳"
    }
]

技术分享图片
我们首先把要展示的树形结构数据一次性准备好,在一对大括号[]里面包裹着我们想要展示的数据,节点用花括号{}以键值对的形式给出,id即为每个节点的id,text则为每个节点显示的文字。当然了,我知道这种一次性载入数据的方式是满足不了日常的工作的,那么接下来我们看这个案例是如果动态想节点添加子节点的。

<body>
    <div style="margin-bottom: 10px;">
        <a href="javascript:void(0);" onclick="appendnodes()" class="easyui-linkbutton" data-options="iconCls:‘icon-add‘">添加节点</a>
    </div>
    <div style="width:200px;height:auto;border:1px solid #ccc;">
        <ul id="tt" class="easyui-tree" url="fruit_data.json"></ul>
    </div>
</body>
<script type="text/javascript">
    function appendnodes() {
        var node = $("#tt").tree("getSelected");
        if(node) {
            var nodes = [{
                "id":"1",
                "text":"pear"
            },{
                "id":"2",
                "text":"grape"
            }];         
            $(‘#tt‘).tree(‘append‘, {
                parent:node.target,
                data:nodes
            });         
        }
    }
</script>

这个案例展示的是水果种类的树形图,加载的json字符串如下:

[{
    "id":0,
    "text":"Foods",
    "children":[{
        "id":1,
        "text":"Fruits",
        "children":[{
            "id":11,
            "text":"apple"
        },{
            "id":12,
            "text":"orange"
        }]
    },{
        "id":2,
        "text":"Vegetables",
        "state":"closed",
        "children":[{
            "id":21,
            "text":"tomato"
        },{
            "id":22,
            "text":"carrot"
        },{
            "id":23,
            "text":"cabbage"
        },{
            "id":24,
            "text":"potato"
        },{
            "id":25,
            "text":"lettuce"
        }]
    }]
}]

当你单击"添加节点"按钮,会触发appendnodes函数,该函数首先判断你是否选中了某一节点,如果没选中则不坐处理。若选中某一节点,则向该节点追加子节点。关键的代码语句是:

$(‘#tt‘).tree(‘append‘, {
    parent:node.target,
    data:nodes
}); 

技术分享图片
这个案例虽然可以动态的追加节点,但是我知道还是满足不了你的日常工作的,你想要与后台交互。下面的是以Java为后台与EasyUi交互的例子。

<body>
    <div style="margin-bottom: 10px;">
        <a href="javascript:void(0);" onclick="appendnodes()" class="easyui-linkbutton" data-options="iconCls:‘icon-add‘">添加节点</a>
    </div>
    <div style="width:300px;height:auto;border:1px solid #ccc;">
        <ul id="tt" class="easyui-tree" url="company_data.json"></ul>
    </div>
</body>
<script type="text/javascript">
    function appendnodes() {
        var node = $("#tt").tree("getSelected");
        if(node) {
            $.get("/drill/demo/wellInfo/tree","key="+node.text,function(data,status,xhr){
                $("#tt").tree(‘append‘,{
                    parent:node.target,
                    data:data.rows
                });
            },"json");
        }
    }
</script>
    @RequestMapping(value="/tree", method={RequestMethod.GET})
    public PageInfo tree(HttpServletRequest request) {
        String key = request.getParameter("key");
        PageInfo pageInfo = new PageInfo();
        List<Map<String, String>> rows = new LinkedList<Map<String, String>>();
        
        Map<String, String> e = new HashMap<String, String>();
        e.put("id",  "1");
        e.put("text", key+"子公司1");
        rows.add(e);
        Map<String, String> e1 = new HashMap<String, String>();
        e1.put("id", "2");
        e1.put("text", key+"子公司2");
        rows.add(e1);       

        pageInfo.setRows(rows);
        pageInfo.setTotal(rows.size());
        
        return pageInfo;
    }

本例子的html代码与上一个例子的唯一区别就是多了一个$.get(url,data,callback,dataType)以ajax交互的代码而已,在ajax请求成功调用回显函数的时候再追加子节点到父节点上。当然,我的后台是通过Java的Spring MVC框架传递回来的,我这里并没有写@ResponseBody是因为在我的Controller类已经写了@RestCotroller注解了如果你的Controller类没有该注解请在你的方法上添加@ResponseBody注解,这样Spring MVC会自动将你的返回的数据转换为json格式,而不是跳转到视图。
至于我封装的那个分页类,你也可以参考借鉴一下,毕竟这不是最重要的。

public class PageInfo<T> {

    private int pageNum;
    
    private int pageSize;
    
    private List<T> rows;

    private Page<T> page;
    
    public PageInfo() {
        super();
    }

    public PageInfo(int pageNum, int pageSize) {
        super();
        this.pageNum = pageNum;
        this.pageSize = pageSize;
    }

    public void startPage() {
        page = PageHelper.startPage(pageNum, pageSize);
    }
    
    public long getTotal() {
        return page.getTotal();
    }

    public void setTotal(long total) {
        if(page == null) {
            page = new Page<T>();
        }
        page.setTotal(total);
    }
    
    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }
    
    @JsonIgnore
    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    @JsonIgnore
    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    
}

技术分享图片





以上是关于使用Sortable.js,ul嵌套3层,树形结构,有个问题是能拖拽出自己当前的容器的主要内容,如果未能解决你的问题,请参考以下文章

Sortable.js移动端拖拽排序的容器li标签里含有其他点击事件如何写

VUE展示无限层级树形数据结构

如何用java与jsp实现树形结构

项目一众筹网05_01_[树形结构开发]菜单维护-树形结构基础知识自关联zTree的介绍和使用如果可以尽量不要嵌套循环时间复杂度和空间复杂度的区别

用 mobx 反应 Sortable JS

递归嵌套for循环map集合方式实现树形结构菜单列表查询