专栏首页web开发树结构数据的展示和编辑-zTree树插件的简单使用

树结构数据的展示和编辑-zTree树插件的简单使用

最近在项目当中遇到一个需求,需要以树结构的方式展示一些数据,并可对每一个树节点做内容的编辑以及树节点的添加和删除,刚好听说有zTree这个插件可以实现这样的需求,所以在项目的这个需求完成之后,在博客里用一个小demo的形式记录一下zTree的简单实用方法。

1、下载zTree插件

zTree的官网地址是:http://www.treejs.cn/v3/main.php#_zTreeInfo

下载地址是:https://gitee.com/zTree/zTree_v3

2、引入相应的css和js文件

  zTreeStyle.css     jquery.min.js     jquery.ztree.core.min.js     jquery.ztree.excheck.min.js     jquery.ztree.exedit.min.js

3、不说废话,直接代码,简洁明了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>zTree的简单实用</title>
    <link rel="stylesheet" href="zTreeStyle.css">
    <script src="jquery.min.js"></script>
    <script src="jquery.ztree.core-3.5.min.js"></script>
    <script src="jquery.ztree.excheck-3.5.min.js"></script>
    <script src="jquery.ztree.exedit-3.5.min.js"></script>
    <style>
        .ztree li {line-height: 25px;}
        .ztree li span.button.switch {height: 20px;margin-top: -7px;}
        .ztree li span.button.ico_open,
        .ztree li span.button.ico_close {background-image: none; width: 0px;margin-left: -2px;}
        .ztree li span.button.ico_docu {background-image: none; width: 0px;}
        .ztree li a {height: 25px;}
        .ztree li span {font-size: 14px;font-family: "PingFang SC", "Hiragino GB", "Microsoft YaHei", "Helvetica Neue", "Helvetica", "ARIAL"}
        .ztree li a.curSelectedNode {height: 18px;}
        .ztree li a.curSelectedNode_Edit{height: 18px;}
        .ztree li a.curSelectedNode_Edit span {display: inline-block;height: 18px;} 
        .ztree li a.curSelectedNode_Edit input {display: inline-block;height: 18px;font-size: 14px;width: 100%;min-width: 150px;font-family: "PingFang SC", "Hiragino GB", "Microsoft YaHei", "Helvetica Neue", "Helvetica", "ARIAL"} 
        .ztree li a.curSelectedNode {max-width: 260px;overflow: hidden;}
        .ztree li span {max-width: 185px;display: inline-block;overflow: hidden;}
        .ztree li span input{width: 150px;}
        .ztree li span.button.add {margin-left: 2px;background-position: -144px 0;vertical-align: top;background-image: url(imgs/jui.png);background-position-x: -278px;background-position-y: -237px;}
        .ztree li span.button.edit {margin-left: 3px;background-position: -144px 0;vertical-align: top;background-image: url(imgs/jui.png);background-position-x: 2px;background-position-y: 3px;}
        .ztree li span.button.remove {background-position: -144px 0;vertical-align: top;background-image: url(imgs/jui.png);background-position-x: -138px;background-position-y: -137px;}
        .ztree li span.button.roots_close, .ztree li span.button.root_close, .ztree li span.button.center_close, .ztree li span.button.bottom_close
         {background-image: url(imgs/jui.png);background-position-x: -77px;background-position-y: -196px;}
        .ztree li span.button.roots_open, .ztree li span.button.root_open, .ztree li span.button.center_open, .ztree li span.button.bottom_open
         {background-image: url(imgs/jui.png);background-position-x: -117px;background-position-y: -196px;}
    </style>
</head>
<body>
    <div>
        <ul id="treeDemo" class="ztree"></ul>
    </div>
</body>
<script>
    //zTree的配置
    var setting = {
        view: {
            addHoverDom: addHoverDom,
            removeHoverDom: removeHoverDom,
            selectedMulti: false
        },
        edit: {
            enable: true,
            editNameSelectAll: true, 
            showRemoveBtn: showRemoveBtn,
            showRenameBtn: showRenameBtn
        },
        data: {
            simpleData: {
                enable: true
            }
        },
        callback: {
            onClick:zTreeOnClick, //点击选中事件
            beforeEditName: beforeEditName,
            beforeRemove: beforeRemove,
            beforeRename: beforeRename,
            onRemove: onRemove,
            onRename: onRename
        }
    };

    //zTree初始化加载的节点树
    var zNodes =[
        { id:1, pId:0, name:"父节点 1", open:true},  //open属性的值true和false,表示是否在初始化加载后展开子节点
        { 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:false},
        { id:31, pId:3, name:"子节点 3-1"},
        { id:32, pId:3, name:"子节点 3-2"},
        { id:33, pId:3, name:"子节点 3-3"},
    ];

    var log, className = "dark";
    function zTreeOnClick(event, treeId, treeNode) {
        console.log('zTreeOnClick');
        console.log(treeNode)
        var treeObj = $.fn.zTree.getZTreeObj("treeDemo"),
            nodes = treeObj.getCheckedNodes(true),
            v = "";
        for (var i = 0; i < nodes.length; i++) {
            v += nodes[i].name + ",";
            console.log("节点id:" + nodes[i].id + "节点名称" + v); //获取选中节点的值
        }
    }
    function beforeEditName(treeId, treeNode) {
        console.log('beforeEditName');
        console.log(treeNode)
        className = (className === "dark" ? "":"dark");
        var zTree = $.fn.zTree.getZTreeObj("treeDemo");
        zTree.selectNode(treeNode);
        zTree.editName(treeNode);
    }
    function beforeRemove(treeId, treeNode) {
        console.log('beforeRemove');
        className = (className === "dark" ? "":"dark");
        var zTree = $.fn.zTree.getZTreeObj("treeDemo");
        zTree.selectNode(treeNode);
        return confirm("确认删除 节点 -- " + treeNode.name + " 吗?");
    }
    function onRemove(e, treeId, treeNode) { //确定删除节点
        console.log('onRemove');
        console.log(treeNode)
    }
    function beforeRename(treeId, treeNode, newName, isCancel) {
        console.log('beforeRename');
        className = (className === "dark" ? "":"dark");
        if (newName.length == 0) {
            setTimeout(function() {
                var zTree = $.fn.zTree.getZTreeObj("treeDemo");
                zTree.cancelEditName();
                alert("节点名称不能为空。");
            }, 0);
            return false;
        }
        return true;
    }
    function onRename(e, treeId, treeNode, isCancel) {
        console.log('onRename')
        console.log(treeNode)
    }
    function showRemoveBtn(treeId, treeNode) {
        return true;
    }
    function showRenameBtn(treeId, treeNode) {
        return true;
    }

    var newCount = 1;
    function addHoverDom(treeId, treeNode) {
        var sObj = $("#" + treeNode.tId + "_span");
        if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
        var addStr = "<span class='button add' id='addBtn_" + treeNode.tId
            + "' title='添加子节点' onfocus='this.blur();'></span>";
        sObj.after(addStr);
        $('.edit').attr('title', '编辑');
        $('.remove').attr('title', '删除');
        var btn = $("#addBtn_"+treeNode.tId);
        if (btn) btn.bind("click", function(){
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            var obj = {id:(100 + newCount), pId:treeNode.id, name:"新增子节点 " + (newCount++)};
            zTree.addNodes(treeNode, obj);
            console.log(obj)
            console.log('添加成功')
            return false;
        });
    };
    function removeHoverDom(treeId, treeNode) {
        $("#addBtn_"+treeNode.tId).unbind().remove();
    };
    
    $(document).ready(function(){
        console.log('ready');
        $.fn.zTree.init($("#treeDemo"), setting, zNodes);
    });
</script>
</html>

其中的<style></style>部分是自定义的样式,主要用来更换插件默认的添加、删除、编辑、展开和收缩的小图标的

4、效果图

1、初始化加载页面后:                                                            

2、选中某个节点后,会出现添加、编辑、删除的操作图标:

3、在第一个父节点新增了一个子节点:

4、在某一个节点点击删除按钮后的确认提示:

5、点击了某一个节点的编辑按钮后,呈现可编辑状态:

6、编辑完成后点击空白处,即可完成编辑:

注:以上代码部分的操作,只是针对DOM做了增删改的操作,如果在具体项目业务中使用的话,还是要另外自己编写相应代码,来保存操作的数据,这里不再一一写出。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue项目图片剪切上传——vue-cropper的使用

    最近自己在研究vue,然后做了一个小型的后台管理系统用来练手,开发过程中,想到了剪切图片上传用户头像的需求。上网百度了一番,发现好多用的都是vue-croppe...

    用户1174387
  • 移动端图片放大滑动查看-插件photoswipe的使用

    最近在开发项目的时候,遇到一个需求,需要移动端实现放大查看图片的功能,然后我就在网上搜索了一下资料,看到了photoswipe这个插件,后来试了试,确实挺好用的...

    用户1174387
  • 原生js实现简单移动端轮播图

    最近项目不是很忙,自己就用原生js写了一个简单的移动端轮播图的小demo,可实现自动轮播和手势滑动轮播,然后就把它记录到个人博客里。还有很多不足的地方,希望多多...

    用户1174387
  • 【Python之旅】第四篇(二):Pyt

        在Python程序的执行过程中,难免会出现异常的情况,如果做的是跟用户交互的程序,当用户输入不可接受的内容时,在可预见的范围内,我们当然是希望可以给用户...

    py3study
  • RTSP协议流媒体视频平台EasyNVR接入云端管理平台EasyNVS显示Running和already是什么原因?

    EasyNVR对接EasyNVS可以实现内网设备的外网访问,利用网络实现按需直播,同时屏蔽各种网络环境问题,适用于有线、WIFI、4G、专网,EasyNVS管理...

    EasyNVR
  • React16中的错误处理

    随着React16的发布越来越接近,我们想宣布一些关于在组件内如何处理JavaScript错误的变化。这些变化包括在React16 Beta版本,并将会成为Re...

    疯狂的技术宅
  • 【NLP】 NLP中应用最广泛的特征抽取模型-LSTM

    本篇介绍在NLP中应用最为广泛的特征抽取模型LSTM。详细介绍LSTM提出的由来及其模型结构,并由此分析了LSTM能够解决RNN不能够对长序列进行处理和训练的原...

    用户1508658
  • iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 错误处理

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923887518 处理错误请求 爱能遮掩一切过错。 当我们在访问一个站...

    iKcamp
  • 【Java SE】Java NIO系列教程(十) DatagramChannel

    Java NIO中的DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数...

    用户1257215
  • python:logging模块(记录打

    logging.basicConfig(**kwargs):创建默认处理器从而将调试消息写至文件,它接受一个字典

    py3study

扫码关注云+社区

领取腾讯云代金券