ZTree基本使用及本人详解

news/2024/7/11 0:45:38 标签: java, thymeleaf, jquery, ZTree

文章目录

  • ZTree树简介
    • 简介
    • ZTree的特点
    • 练习ztree之前的小建议
    • ZTree文件介绍
    • ZTree的配置介绍
  • ZTree使用案例
    • 需求1:前端初始化数据(标准json数据)
      • 前端代码
    • 需求2:后端查询ztree数据(简单JSON数据)+需求3:设置节点默认选中+需求4:【添加/编辑/删除】节点+需求5:自定义图标固定和不固定显示
      • 前端代码
      • 后端代码
    • 需求6:左侧菜单栏
      • 前端代码
    • 需求7:拖拽节点高级控制
      • 前端代吗
    • 需求8:2棵树之间的数据交互
      • 前端代吗

ZTree_1">ZTree树简介

简介

在这里插入图片描述

ZTree_4">ZTree的特点

在这里插入图片描述

练习ztree之前的小建议

如果一上来看官网估计找不准哪个是配置,哪个是事件回调函数…,可以把源码下载本地,然后进入
D:\zTree_v3-master\demo\cn文件下点开index.heml里面有所有的案例,这时候精确找到自己要练习的案例网页代码,然后F12进行删减,把多余的css+js+文字说明,都删掉这样方便整体练习及了解。

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

ZTree_14">ZTree文件介绍

在这里插入图片描述

ZTree_16">ZTree的配置介绍

在这里插入图片描述

ZTree_19">ZTree使用案例

需求1:前端初始化数据(标准json数据)

说明:前端初始化数据,且数据采用标准json数据格式,构建最简单的树。
注意:ZTree依赖于jquery实现,所以要先加载css -》jquery -》ztree.js

在这里插入图片描述

案例原型对应官网下面的demo

在这里插入图片描述

前端代码

javascript"><head>
	<!--先加载css,再加载js,否则可能出错-->
    <link th:href="@{bootstrap-3.4.1-dist/css/bootstrap.css}" rel="stylesheet" />
    <link th:href="@{bootstrap-3.4.1-dist/css/bootstrap-theme.css}" rel="stylesheet" />
    <!--<link th:href="@{zTree_v3-master/css/metroStyle/metroStyle.css}" rel="stylesheet" type="text/css" />-->
    <link th:href="@{zTree_v3-master/css/zTreeStyle/zTreeStyle.css}" rel="stylesheet" type="text/css" />
    <link th:href="@{zTree_v3-master/css/demo.css}" rel="stylesheet" type="text/css" />
    <!--切记:先加载jquery的js,再加载bootstrap.js-->
    <script th:src="@{jquery/jquery3.6.0.js}"></script>
    <script th:src="@{bootstrap-3.4.1-dist/js/bootstrap.js}"></script>
    <script type="text/javascript" th:src="@{zTree_v3-master/js/jquery.ztree.all.js}" ></script>
</head>    
javascript"><!--需求1:前端初始化数据(标准json数据)-->
<div class="col-md-7">
    <hr><p>需求1:前端初始化数据(标准json数据)</p>
    <ul id="treeDemo" class="ztree"></ul>
</div>
javascript">//需求1配置:前端初始化数据(标准json数据)
var setting0 = {
    data: {
        simpleData: {
            enable: true,  //true 、 false 分别表示 使用 、 不使用 简单数据模式
            idKey: "id",  //节点数据中保存唯一标识的属性名称
            pIdKey: "parentId",    //节点数据中保存其父节点唯一标识的属性名称
            rootPId: -1  //用于修正根节点父节点数据,即 pIdKey 指定的属性值
        },
        key: {
            name: "name"  //zTree 节点数据保存节点名称的属性名称  默认值:"name"
        }
    }
};
//需求1:前端初始化数据
var zNodes = [
    //注意,数据中的 menuName 必须与 settingss 中key 中定义的name一致,否则找不到
    {name:"父节点1", open:true, children:[
            {name:"子节点1"}, {name:"子节点2"}]},
    {name:"父节点2", open:true, children:[
            {name:"子节点3"}, {name:"子节点4"}]}
];
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting0, zNodes); //初始化树
zTreeObj.expandAll(true);    //true 节点全部展开、false节点收缩

需求2:后端查询ztree数据(简单JSON数据)+需求3:设置节点默认选中+需求4:【添加/编辑/删除】节点+需求5:自定义图标固定和不固定显示

该案例要实现4个功能:
1)后端查询ztree数据
2)设置节点默认选中
3)【添加/编辑/删除】节点
4)自定义图标固定和不固定显示
为了方便这4个功能写到一个案例中

碰到的问题1:增加按钮一直显示空心正方形,而没有小+号图标,
解决方案:
第一种:css样式由zTreeStyle.css -》 调整为metroStyle.css,也就是使用黑白主题的样式,就会显示添加图标
第二种:使用zTreeStyle.css样式的时候,style标签追加图标地址,也就是下面的
在这里插入图片描述
碰到的问题2:自定义添加按钮一直无限的增加显示出来
解决方案:js中使用下面的校验,详情请看方法 function addDiyDom()
if (treeNode.editNameFlag || $(“#” + treeNode.tId + “_add”).length>0) return; //注意:该条件保证添加图标不会一直重复添加

在这里插入图片描述

案例原型对应官网下面的demo
在这里插入图片描述
在这里插入图片描述

前端代码

javascript"><!--需求4和需求5配置:必须设置图标url,否则图标不显示,只显示个空白正方形-->
<style type="text/css">
     .ztree li span.button.icon01{margin:0; background: url(zTree_v3-master/css/zTreeStyle/img/diy/1_close.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
     .ztree li span.button.icon02{margin:0; background: url(zTree_v3-master/css/zTreeStyle/img/diy/5.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
 </style>
javascript"><!--需求2:后端查询ztree数据(简单JSON数据)-->
<div class="col-md-7">
   <hr><p>需求2:后端查询ztree数据(简单JSON数据)</p>
   <ul id="ajaxQueryTree" class="ztree"></ul>
</div>
javascript">//需求2配置:后端查询ztree数据(简单JSON数据)
    var setting1 = {
        data: {
            simpleData: {
                enable: true,  //true 、 false 分别表示 使用 、 不使用 简单数据模式
                idKey: "id",  //节点数据中保存唯一标识的属性名称
                pIdKey: "parentId",    //节点数据中保存其父节点唯一标识的属性名称
                rootPId: -1  //用于修正根节点父节点数据,即 pIdKey 指定的属性值
            },
            key: {
                name: "name"  //zTree 节点数据保存节点名称的属性名称  默认值:"name"
            }
        },
        check:{
            enable:true,  //true 、 false 分别表示 显示 、不显示 复选框或单选框
            nocheckInherit:true  //当父节点设置 nocheck = true 时,设置子节点是否自动继承 nocheck = true
        },
        edit: {
            enable: true
        },
        callback: {
            beforeRemove: zTreeBeforeRemove,     //用于捕获节点被删除之前的事件回调函数,并且根据返回值确定是否允许删除操作
            onRemove: zTreeOnRemove,            //用于捕获删除节点之后的事件回调函数
            beforeRename: zTreeBeforeRename,    //用于捕获节点编辑名称结束(Input 失去焦点 或 按下 Enter 键)之后,更新节点名称数据之前的事件回调函数,并且根据返回值确定是否允许更改名称的操作
            onRename: zTreeOnRename             //用于捕获节点编辑名称结束之后的事件回调函数
        },
        view : {
            addDiyDom: addDiyDom,               //用于在节点上固定显示用户自定义控件
            selectedMulti: false,                //设置是否允许同时选中多个节点
            showLine : true,                    //设置 zTree 是否显示节点之间的连线
            addHoverDom: addHoverDom,           //用于当鼠标移动到节点上时,显示用户自定义控件
            removeHoverDom: removeHoverDom,     //用于当鼠标移出节点时,隐藏用户自定义控件
        }
    };
    //需求2:后端查询ztree数据
    $(document).ready(function(){
        $.ajax({
            type:"get",
            url:"http://localhost:8888/getEquipmentList",
            async:true,
            success:function(res){
                zTreeObj = $.fn.zTree.init($("#ajaxQueryTree"), setting1, res.info); //初始化树
                zTreeObj.expandAll(true);   //true 节点全部展开、false节点收缩

                //需求3:设置节点默认选中
                var node = zTreeObj.getNodeByParam("id", 0);
                zTreeObj.checkNode(node, true, false, false);
            }
        });
    });
    //需求4:【添加/编辑/删除】节点
    var newCount = 100;
    function addHoverDom(treeId, treeNode) {
        var sObj = $("#" + treeNode.tId + "_span");
        if (treeNode.editNameFlag || $("#" + treeNode.tId + "_add").length>0) return;   //注意:该条件保证添加图标不会一直重复添加
        var addStr = "<span class='button icon01' id='" + treeNode.tId + "_add' title='add'></span>";
        sObj.after(addStr);
        var btn = $("#"+treeNode.tId + "_add");
        if (btn) btn.bind("click", function(){
            var zTree = $.fn.zTree.getZTreeObj("ajaxQueryTree");
            zTree.addNodes(treeNode, {id:newCount, pId:treeNode.id, name:"add_" + (newCount++)});
            return false;
        });
    }
    function removeHoverDom(treeId, treeNode) {
        $("#" + treeNode.tId + "_add").unbind().remove();
    }
    function zTreeBeforeRemove(treeId, treeNode) {
        alert("删除节点前{:" + "id=" + treeNode.id + ", " +  "parentId=" + treeNode.parentId + ", " + "name=" + treeNode.name + ", " + "level=" + treeNode.level +", "+ "tId=" + treeNode.tId + "}");
    }
    function zTreeOnRemove(event, treeId, treeNode) {
        alert("删除节点后{:" + "id=" + treeNode.id + ", " +  "parentId=" + treeNode.parentId + ", " + "name=" + treeNode.name + ", " + "level=" + treeNode.level +", "+ "tId=" + treeNode.tId + "}");
    }
    function zTreeBeforeRename(treeId, treeNode, newName, isCancel) {
        alert("编辑节点前{:" + "id=" + treeNode.id + ", " +  "parentId=" + treeNode.parentId + ", " + "name=" + treeNode.name + ", " + "level=" + treeNode.level +", "+ "tId=" + treeNode.tId + "}");
    }
    function zTreeOnRename(event, treeId, treeNode, isCancel) {
        alert("编辑节点后{:" + "id=" + treeNode.id + ", " +  "parentId=" + treeNode.parentId + ", " + "name=" + treeNode.name + ", " + "level=" + treeNode.level +", "+ "tId=" + treeNode.tId + "}");
    }
    //需求5:自定义图标固定和不固定显示
    function addDiyDom(treeId, treeNode) {
        if (treeNode.id == 3) {
            var sObj = $("#" + treeNode.tId + "_span");
            if (treeNode.editNameFlag || $("#" + treeNode.tId + "_add").length>0) return;   //注意:该条件保证添加图标不会一直重复添加
            var addStr = "<span class='button icon02' id='" + treeNode.tId + "_add' title='add'></span>";
            sObj.after(addStr);
            var btn = $("#"+treeNode.tId + "_add");
            if (btn) btn.bind("click", function(){
                var zTree = $.fn.zTree.getZTreeObj("ajaxQueryTree");
                zTree.addNodes(treeNode, {id:newCount, pId:treeNode.id, name:"add_" + (newCount++)});
                return false;
            });
        }
    }

后端代码

Equipment实体

java">package com.example.demo.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 装备
 * @Author 211145187
 * @Date 2022/3/26 10:15
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Equipment {
    //id
    private int id;
    //父id
    private int parentId;
    //名称
    private String name;
}

Controller代码

javascript">//ZTree数据缓存
 private ConcurrentHashMap<String, List<Equipment>> zTreeCache = new ConcurrentHashMap<>();
----------------------------------------------------------------------------------------------
@PostConstruct
public void initCacheEquipmentList() {
    List<Equipment> equipmentList = new ArrayList<>();
    equipmentList.add(new Equipment(0, -1, "装备"));
    equipmentList.add(new Equipment(1, 0, "陆"));
    equipmentList.add(new Equipment(2, 0, "海"));
    equipmentList.add(new Equipment(3, 0, "空"));
    equipmentList.add(new Equipment(4, 1, "东风2号"));
    equipmentList.add(new Equipment(5, 1, "坦克"));
    equipmentList.add(new Equipment(6, 2, "潜艇"));
    equipmentList.add(new Equipment(7, 2, "巡洋舰"));
    equipmentList.add(new Equipment(8, 3, "隐形飞机"));
    zTreeCache.put("equipmentList", equipmentList);
}
----------------------------------------------------------------------------------------------
//查询ZTree
@GetMapping(value = "/getEquipmentList")
@ResponseBody
public Response<List<Equipment>> getEquipmentList(Model model) {
    List<Equipment> equipmentList = zTreeCache.get("equipmentList");
    model.addAttribute("equipmentList", equipmentList);
    equipmentList.stream().forEach(System.out::println);
    return Response.success(equipmentList);
}

需求6:左侧菜单栏

注意点1: 初始化组件加载方法 $(document).ready(function(){})不知道内部干了啥,我添加了注释,方便对照理解
注意点2:方法beforeClick()里面执行流程很绕,所以我梳理了下在方法上加入了执行流程说明,方便对照理解

碰到的问题:因为我所有案例写在同一个页面,加入菜单案例后把别的案例的样式都给改变了
解决方案:设置css样式时先进行id过滤 ,详情看下面的
在这里插入图片描述

在这里插入图片描述

案例原型对应官网下面的demo

在这里插入图片描述

前端代码

javascript"><!--需求6:左侧菜单栏   注意:按id进行筛选,否则会干扰其他树结构样式-->
<style type="text/css">
     #leftMenuTree li a.level0 {width:200px;height: 20px; text-align: center; display:block; background-color: #0B61A4; border:1px silver solid;}
     #leftMenuTree li a.level0.cur {background-color: #66A3D2; }
     #leftMenuTree li a.level0 span {display: block; color: white; padding-top:3px; font-size:12px; font-weight: bold;word-spacing: 2px;}
     #leftMenuTree li a.level0 span.button {	float:right; margin-left: 10px; visibility: visible;display:none;}
     #leftMenuTree li span.button.switch.level0 {display:none;}
 </style>
javascript"><!--需求6:左侧菜单栏-->
<!--左侧菜单栏 注意:ul的class必须为ztree否则样式没效果,同时div的class指定为zTreeDemoBackground left-->
<div class="col-md-7">
    <hr><p>需求6:左侧菜单栏</p>
    <ul id="leftMenuTree" class="ztree"></ul>
</div>
javascript">//需求6配置:左侧菜单栏
    var setting6 = {
        data: {
            simpleData: {
                enable: true,  //true 、 false 分别表示 使用 、 不使用 简单数据模式
            }
        },
        callback: {
            onNodeCreated: this.onNodeCreated,  //用于捕获节点生成 DOM 后的事件回调函数
            beforeClick: this.beforeClick,      //用于捕获单击节点之前的事件回调函数,并且根据返回值确定是否允许单击操作
            onClick: this.onClick               //用于捕获节点被点击的事件回调函数
        },
        view : {
            selectedMulti: false,                //设置是否允许同时选中多个节点
            showLine : true,                    //设置 zTree 是否显示节点之间的连线
            dblClickExpand: false               //双击节点时,是否自动展开父节点的标识
        }
    };
    var curMenu = null, zTree_Menu = null;
    var zNodes6 =[
        { id:1, pId:0, name:"主菜单 1", open:true},        //open:true,记录 treeNode 节点的 展开 / 折叠 状态
        { id:11, pId:1, name:"子菜单 1-1"},
        { id:111, pId:11, name:"叶子节点 1-1-1"},
        { id:112, pId:11, name:"叶子节点 1-1-2"},
        { id:113, pId:11, name:"叶子节点 1-1-3"},
        { id:114, pId:11, name:"叶子节点 1-1-4"},
        { id:12, pId:1, name:"子菜单 1-2"},
        { id:121, pId:12, name:"叶子节点 1-2-1"},
        { id:122, pId:12, name:"叶子节点 1-2-2"},
        { id:123, pId:12, name:"叶子节点 1-2-3"},
        { id:124, pId:12, name:"叶子节点 1-2-4"},
        { id:2, pId:0, name:"主菜单 2"},
        { id:21, pId:2, name:"子菜单 2-1"},
        { id:211, pId:21, name:"叶子节点 2-1-1"},
        { id:212, pId:21, name:"叶子节点 2-1-2"},
        { id:213, pId:21, name:"叶子节点 2-1-3"},
        { id:214, pId:21, name:"叶子节点 2-1-4"},
        { id:22, pId:2, name:"子菜单 2-2"},
        { id:221, pId:22, name:"叶子节点 2-2-1"},
        { id:222, pId:22, name:"叶子节点 2-2-2"},
        { id:223, pId:22, name:"叶子节点 2-2-3"},
        { id:224, pId:22, name:"叶子节点 2-2-4"}
    ];
    $(document).ready(function(){
         $.fn.zTree.init($("#leftMenuTree"), setting6, zNodes6); //初始化树
        zTree_Menu = $.fn.zTree.getZTreeObj("leftMenuTree");
        curMenu = zTree_Menu.getNodes()[0].children[0].children[0]; //curMenu {id: 111, pId: 11, name: '叶子节点 1-1-1', level: 2, tId: 'leftMenuTree_3,....
        zTree_Menu.selectNode(curMenu);     //选中指定节点
        var a = $("#" + zTree_Menu.getNodes()[0].tId + "_a");       //获取id=“treeDemo_1_a” title="主菜单 1"的标签对象
        a.addClass("cur");  //添加css
    });
    function onClick(event, treeId, node) {
        alert("Do what you want to do!");
    }
    /**
     * 判断是否为父节点
     *      true:判断节点level === 0
     *          true:将第一个子节点“叶子结点1-1-1”赋值给pNode -》 按条件(pNode && pNode.level !==0)循环获取它的根节点“主菜单1”赋值给pNode -》 按条件(pNode !== node)判断当点击主菜单2时移除class(”cur“)等相关操作 -》判断children的open状态,进行相应的展开
     *          false:展开/折叠 指定的节点
     *      false:返回
     * @param treeId
     * @param node
     * @returns {boolean}
     */
    function beforeClick(treeId, node) {    //treeId:leftMenuTree   node为每次点击的对象 node {id: 2, pId: null, name: '主菜单 2',...
        if (node.isParent) {
            if (node.level === 0) {
                var pNode = curMenu;
                while (pNode && pNode.level !==0) {
                    pNode = pNode.getParentNode();  //获取到根节点
                }
                if (pNode !== node) {
                    var a = $("#" + pNode.tId + "_a");
                    a.removeClass("cur");
                    zTree_Menu.expandNode(pNode, false);
                }
                a = $("#" + node.tId + "_a");
                a.addClass("cur");

                var isOpen = false;
                for (var i=0,l=node.children.length; i<l; i++) {
                    if(node.children[i].open) {     //判断节点children的open状态
                        isOpen = true;
                        break;
                    }
                }
                if (isOpen) {
                    zTree_Menu.expandNode(node, true);
                    curMenu = node;
                } else {
                    zTree_Menu.expandNode(node.children[0].isParent?node.children[0]:node, true);
                    curMenu = node.children[0];
                }
            } else {
                zTree_Menu.expandNode(node);    //展开 / 折叠 指定的节点
            }
        }
        return !node.isParent;
    }

需求7:拖拽节点高级控制

注意说明1:zNodes7配置中:
open:true,记录 treeNode节点的【展开/折叠】状态
drag:false,禁止拖拽
childOuter:false,禁止子节点移走
dropRoot该属性未知,我查不到
dropInner:false:不变为文件夹
注意说明2:方法dropPrev()+dropInner()+dropNext()就是用来判断【true/false】的

碰到的问题1: 为啥有的移动完目标节点变为文件夹,而“禁止子节点移走 2”下的移动完双方都还是文件,而没有目标节点变为文件夹
解决方案:setting -》edit -》drag -》 inner属性,inner属性用来控制移动后目标节点是否变为文件夹【true:目标节点变为文件夹/false:不变为文件夹】

在这里插入图片描述

案例原型对应官网下面的demo

在这里插入图片描述

前端代吗

javascript"><!--需求7:拖拽节点高级控制-->
<div class="col-md-7">
     <hr><p>需求7:拖拽节点高级控制</p>
     <ul id="moveTree" class="ztree"></ul>
 </div>
javascript">//需求7:拖拽节点高级控制
    var setting7 = {
        edit: {
            drag: {
                autoExpandTrigger: true,    //拖拽时父节点自动展开是否触发 onExpand 事件回调函数
                prev: dropPrev,     //拖拽到目标节点时,设置是否允许移动到目标节点前面的操作
                inner: dropInner,   //拖拽到目标节点时,设置是否允许成为目标节点的子节点    注意:inner属性用来控制移动后目标节点是否变为文件夹【true:目标节点变为文件夹/false:不变为文件夹】
                next: dropNext      //拖拽到目标节点时,设置是否允许移动到目标节点后面的操作
            },
            enable: true,           //设置 zTree 是否处于编辑状态
            showRemoveBtn: false,   //设置是否显示删除按钮
            showRenameBtn: false    //设置是否显示编辑名称按钮
        },
        data: {
            simpleData: {
                enable: true    //true 、 false 分别表示 使用 、 不使用 简单数据模式
            }
        },
        callback: {
            beforeDrag: beforeDrag,         //用于捕获节点被拖拽之前的事件回调函数,并且根据返回值确定是否允许开启拖拽操作
            beforeDrop: beforeDrop,         //用于捕获节点拖拽操作结束之前的事件回调函数,并且根据返回值确定是否允许此拖拽操作
            beforeDragOpen: beforeDragOpen, //用于捕获拖拽节点移动到折叠状态的父节点后,即将自动展开该父节点之前的事件回调函数,并且根据返回值确定是否允许自动展开操作
            onDrag: onDrag,                 //用于捕获节点被拖拽的事件回调函数
            onDrop: onDrop,                 //用于捕获节点拖拽操作结束的事件回调函数
            onExpand: onExpand              //用于捕获节点被展开的事件回调函数
        }
    };
    var zNodes7 =[
        { id:1, pId:0, name:"随意拖拽 1", open:true},   //open:true,记录 treeNode节点的【展开/折叠】状态
        { id:11, pId:1, name:"随意拖拽 1-1"},
        { id:12, pId:1, name:"随意拖拽 1-2", open:true},
        { id:121, pId:12, name:"随意拖拽 1-2-1"},
        { id:122, pId:12, name:"随意拖拽 1-2-2"},
        { id:123, pId:12, name:"随意拖拽 1-2-3"},
        { id:13, pId:1, name:"禁止拖拽 1-3", drag:false},    //drag:false,禁止拖拽
        { id:131, pId:13, name:"禁止拖拽 1-3-1", drag:false},
        { id:132, pId:13, name:"禁止拖拽 1-3-2", drag:false},
        { id:132, pId:13, name:"禁止拖拽 1-3-3", drag:false},
        { id:2, pId:0, name:"禁止子节点移走 2", open:true, childOuter:false},  //childOuter:false,禁止子节点移走
        { id:21, pId:2, name:"我不想成为父节点 2-1", dropInner:false},
        { id:22, pId:2, name:"我不要成为根节点 2-2", dropRoot:false},   //dropRoot该属性未知,我查不到
        { id:23, pId:2, name:"拖拽试试看 2-3"},
        { id:3, pId:0, name:"禁止子节点排序/增加 3", open:true, childOrder:false, dropInner:false},  //dropInner:false:不变为文件夹
        { id:31, pId:3, name:"随意拖拽 3-1"},
        { id:32, pId:3, name:"随意拖拽 3-2"},
        { id:33, pId:3, name:"随意拖拽 3-3"}
    ];
    function dropPrev(treeId, nodes, targetNode) {
        var pNode = targetNode.getParentNode();
        if (pNode && pNode.dropInner === false) {
            return false;
        } else {
            for (var i=0,l=curDragNodes.length; i<l; i++) {
                var curPNode = curDragNodes[i].getParentNode();
                if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }
    function dropInner(treeId, nodes, targetNode) {
        if (targetNode && targetNode.dropInner === false) {
            return false;
        } else {
            for (var i=0,l=curDragNodes.length; i<l; i++) {
                if (!targetNode && curDragNodes[i].dropRoot === false) {
                    return false;
                } else if (curDragNodes[i].parentTId && curDragNodes[i].getParentNode() !== targetNode && curDragNodes[i].getParentNode().childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }
    function dropNext(treeId, nodes, targetNode) {
        var pNode = targetNode.getParentNode();
        if (pNode && pNode.dropInner === false) {
            return false;
        } else {
            for (var i=0,l=curDragNodes.length; i<l; i++) {
                var curPNode = curDragNodes[i].getParentNode();
                if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }
    var log, className = "dark", curDragNodes, autoExpandNode;
    function beforeDrag(treeId, treeNodes) {
        className = (className === "dark" ? "":"dark");
        for (var i=0,l=treeNodes.length; i<l; i++) {
            if (treeNodes[i].drag === false) {
                curDragNodes = null;
                return false;
            } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
                curDragNodes = null;
                return false;
            }
        }
        curDragNodes = treeNodes;
        return true;
    }
    function beforeDragOpen(treeId, treeNode) {
        autoExpandNode = treeNode;
        return true;
    }
    function beforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) {
        className = (className === "dark" ? "":"dark");
        return true;
    }
    function onDrag(event, treeId, treeNodes) {
        className = (className === "dark" ? "":"dark");
    }
    function onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) {
        className = (className === "dark" ? "":"dark");
    }
    function onExpand(event, treeId, treeNode) {
        if (treeNode === autoExpandNode) {
            className = (className === "dark" ? "":"dark");
        }
    }
    $(document).ready(function(){
        $.fn.zTree.init($("#moveTree"), setting7, zNodes7);
    });

需求8:2棵树之间的数据交互

注意说明:该案例需单独引入demo.css,同时div中的class名字好像必须指定官网给定的那个名字,比如class=“content_wrap”,class=“zTreeDemoBackground left”,class=“zTreeDemoBackground right”,
否则外面没有边框背景样式。

在这里插入图片描述

案例原型对应官网下面的demo

在这里插入图片描述

前端代吗

javascript"><!--需求82棵树之间的数据交互-->
<div class="content_wrap">
    <div class="zTreeDemoBackground left">
        <hr><p>需求82棵树之间的数据交互</p>
        <ul id="leftMoveTree" class="ztree"></ul>
    </div>
    <div class="zTreeDemoBackground right">
        <ul id="rightMoveTree" class="ztree"></ul>
    </div>
</div>
javascript">//需求8:2棵树之间的数据交互
    var setting8 = {
        edit: {
            enable: true,           //设置 zTree 是否处于编辑状态
            showRemoveBtn: false,   //设置是否显示删除按钮
            showRenameBtn: false    //设置是否显示编辑名称按钮
        },
        data: {
            simpleData: {
                enable: true    //true 、 false 分别表示 使用 、 不使用 简单数据模式
            }
        },
        callback: {
            beforeDrag: beforeDrag8,    //用于捕获节点被拖拽之前的事件回调函数,并且根据返回值确定是否允许开启拖拽操作
            beforeDrop: beforeDrop8     //用于捕获节点拖拽操作结束之前的事件回调函数,并且根据返回值确定是否允许此拖拽操作
        }
    };
    var zNodes8 =[
        { id:1, pId:0, name:"父节点 1", open:true},
        { id:11, pId:1, name:"叶子节点 1-1"},
        { id:12, pId:1, name:"叶子节点 1-2"},
        { id:13, pId:1, name:"叶子节点 1-3"},
        { id:2, pId:0, name:"父节点 2", open:true},
        { id:21, pId:2, name:"叶子节点 2-1"},
        { id:22, pId:2, name:"叶子节点 2-2"},
        { id:23, pId:2, name:"叶子节点 2-3"},
        { id:3, pId:0, name:"父节点 3", open:true},
        { id:31, pId:3, name:"叶子节点 3-1"},
        { id:32, pId:3, name:"叶子节点 3-2"},
        { id:33, pId:3, name:"叶子节点 3-3"}
    ];
    function beforeDrag8(treeId, treeNodes) {
        for (var i=0,l=treeNodes.length; i<l; i++) {
            if (treeNodes[i].drag === false) {
                return false;
            }
        }
        return true;
    }
    function beforeDrop8(treeId, treeNodes, targetNode, moveType) {
        return targetNode ? targetNode.drop !== false : true;
    }
    $(document).ready(function(){
        $.fn.zTree.init($("#leftMoveTree"), setting8, zNodes8);
        $.fn.zTree.init($("#rightMoveTree"), setting8);
    });

http://www.niftyadmin.cn/n/898180.html

相关文章

前端UI框架介绍

文章目录一、主流3大框架介绍二、JavaScript构建工具三、UI框架介绍1.iView2.ElementUI3.ICE4.VantUI5.AtUI6.CubeUI混合开发 ↓7.Flutter8.lonic微信小程序 ↓9.mpvue10.WeUI四、后端技术一、主流3大框架介绍 二、JavaScript构建工具 三、UI框架介绍 1.iView 2.ElementUI 3.IC…

JavaScript入门及基础知识介绍

文章目录JavaScript大纲1.概述2.历史3.数据类型3.1严格检查格式3.2 字符串3.3数组3.4 对象3.5 流程控制3.6 Map和Set3.7 iterator4.函数4.1定义函数4.2变量的作用域4.3方法5.内部对象5.1 Date5.2 JSON5.3 Ajax6.面向对象编程6.1什么是面向对象7.操作BOM对象&#xff08;重点&am…

java小工具util系列9:检测一个字符串是否是时间格式

解决方案 /** * 检测一个字符串是否是时间格式* param str 请求字符串* author liudz* date 2019/12/17* return 执行结果**/ public static boolean isValidDate(String str) {boolean convertSuccess true;// 指定日期格式为四位年/两位月份/两位日期&#xff0c;注意yyyy…

Sppring集成Quartz简单案例详解 包括(添加、停止、恢复、删除任务、获取下次执行时间等)

文章目录一、Quartz简介1.Java主流三大定时任务框架优缺点2.什么是Quartz&#xff1f;3.模型图4.名词解释名词举例关系图-自己理解(重点掌握) job(重点掌握) JobDetail(重点掌握) JobExecutionContext(重点掌握) JobDataMap(重点掌握) Trigger、SimpleTrigger、CronTrigger(了解…

SpringBoot项目的html页面使用axios进行get post请求

说明&#xff1a;本项目为SpringBoot项目而不是vue项目&#xff0c;本项目用于练习axios使用get及post请求 get和post请求都采用两种方式进行配置&#xff0c;并注明易错点 文章目录1.axios是什么2.vue项目为什么使用axios&#xff0c;而不使用jquery&#xff1f;3.SpringBoot项…

《基础篇第1章:vue2简介》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结

文章目录vue2大纲第1章&#xff1a;vue简介1.1Vue是什么&#xff1f;1.2谁开发的&#xff1f;1.3vue的特点1.4学习Vue之前要掌握的JavaScript基础知识1.5初识vue.html1.6 Vue 框架有以下特点:本人其他相关文章链接vue2大纲 第1章&#xff1a;vue简介 1.1Vue是什么&#xff1f;…

《基础篇第2章:vue2基础》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结

文章目录第2章&#xff1a;vue2基础 - 指令2.1如何使用vue2.2vue模板语法2.3文本渲染 (都是针对标签属性)2.3.1 v-text2.3.2 v-once2.3.3 v-html2.4数据绑定2.5el和data两种写法2.6MVVM模型2.7数据代理2.7.1回顾Object.defineProperty()2.7.2何为数据代理2.7.3vue中的数据代理2…

vue组件通信案例练习(包含:父子组件通信及平行组件通信)

文章目录一、案例概述二、代码准备工作&#xff1a;案例1.1&#xff1a;父组件向子组件传值&#xff08;或者叫&#xff1a;子组件使用父组件属性&#xff09;&#xff0c;采用v-bind方式实现案例1.2&#xff1a;子组件向父组件传值&#xff08;或者叫&#xff1a;子组件调用父…