欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ZTree自定义icon

程序员文章站 2022-04-22 20:20:23
...

在写一个界面,用到了ZTree插件。
我的目录分类有:大目录,小目录和文件。默认的ZTree并不满足我的需求,就需要一些定制化的开发。

增加变量

jquery.ztree.core.js文件里有一个变量组,分别表示打开的文件夹,关闭的文件夹,文件。

    _consts = {
            ...
            folder: {
                OPEN: "open",
                CLOSE: "close",
                DOCU: "docu"
            },
            ...
        },

在我的项目里默认:

  • _consts.folder.OPEN 大目录打开状态
  • _consts.folder.CLOSE 大目录关闭状态
  • _consts.folder.DOCU 文件

为了满足我的需求,所以我在项目里添加了小目录的状态,添加后的代码如下:

 _consts = {
            ...
            folder: {
                OPEN: "open",
                CLOSE: "close",
                DOCU: "docu",
                OPEN2: "open2",
                CLOSE2: "close2"
            },
            ...
        },

其中

  • _consts.folder.OPEN2 小目录打开状态
  • _consts.folder.CLOSE2 小目录关闭状态

修改节点状态

只修改了这些,仅仅是添加了状态变量。
然后就是根据节点类型来选择不同的状态。
还是在jquery.ztree.core.jsexpandCollapseNode方法里面有这些代码

       expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) {
                ...
                //如果是目录
               if (isParent) {
                    //更新节点的打开状态
                    node.open = !node.open;
                    if (node.iconOpen && node.iconClose) {
                        icoObj.attr("style", view.makeNodeIcoStyle(setting, node));
                    }
                    //如果当前节点的状态为打开
                    if (node.open) {
                        view.replaceSwitchClass(node, switchObj, consts.folder.OPEN);
                        view.replaceIcoClass(node, icoObj, consts.folder.OPEN);
                        if (animateFlag == false || setting.view.expandSpeed == "") {
                            ulObj.show();
                            tools.apply(callback, []);
                        } else {
                            if (children && children.length > 0) {
                                ulObj.slideDown(setting.view.expandSpeed, callback);
                            } else {
                                ulObj.show();
                                tools.apply(callback, []);
                            }
                        }
                    } else { //如果当前的节点状态为关闭
                        view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE);
                        view.replaceIcoClass(node, icoObj, consts.folder.CLOSE);
                        if (animateFlag == false || setting.view.expandSpeed == "" || !(children && children.length > 0)) {
                            ulObj.hide();
                            tools.apply(callback, []);
                        } else {
                            ulObj.slideUp(setting.view.expandSpeed, callback);
                        }
                    }
                } else {
                    tools.apply(callback, []);
                }
            },

这些代码会对当前操作的节点的样式进行重绘。代码的大致意思:

IF 当前节点为目录 THEN
    IF 目录为打开状态 THEN
        重绘该节节为打开样式;
    ELSE
        重绘该节点为关闭样式;
    END IF  
END IF

所以我需要在这里添加我的小目录的样式

        expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) {
                 ...
                  if (isParent) {
                    node.open = !node.open;
                    if (node.iconOpen && node.iconClose) {
                        icoObj.attr("style", view.makeNodeIcoStyle(setting, node));
                    }
                    //判断当前目录类型 0:大目录  1:小目录
                    var dir = node.directory;
                    if (node.open) {
                      //如果是小目录 替换为小目录的打开状态
                        if (dir == 1) {
                            view.replaceSwitchClass(node, switchObj, consts.folder.OPEN2);
                            view.replaceIcoClass(node, icoObj, consts.folder.OPEN2);
                        } else {
                            view.replaceSwitchClass(node, switchObj, consts.folder.OPEN);
                            view.replaceIcoClass(node, icoObj, consts.folder.OPEN);
                        }

                        if (animateFlag == false || setting.view.expandSpeed == "") {
                            ulObj.show();
                            tools.apply(callback, []);
                        } else {
                            if (children && children.length > 0) {
                                ulObj.slideDown(setting.view.expandSpeed, callback);
                            } else {
                                ulObj.show();
                                tools.apply(callback, []);
                            }
                        }
                    } else {
                        //如果是小目录 替换为小目录的关闭状态
                        if (dir == 1) {
                            view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE2);
                            view.replaceIcoClass(node, icoObj, consts.folder.CLOSE2);
                        } else {
                            view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE);
                            view.replaceIcoClass(node, icoObj, consts.folder.CLOSE);
                        }


                        if (animateFlag == false || setting.view.expandSpeed == "" || !(children && children.length > 0)) {
                            ulObj.hide();
                            tools.apply(callback, []);
                        } else {
                            ulObj.slideUp(setting.view.expandSpeed, callback);
                        }
                    }
                } else {
                    tools.apply(callback, []);
                }
            },

然后就是在replaceSwitchClassreplaceIcoClass 方法里加上我们的两个小目录状态

 replaceSwitchClass: function (node, obj, newName) {
                if (!obj) return;
                var tmpName = obj.attr("class");
                if (tmpName == undefined) return;
                var tmpList = tmpName.split("_");
                switch (newName) {
                    case consts.line.ROOT:
                    case consts.line.ROOTS:
                    case consts.line.CENTER:
                    case consts.line.BOTTOM:
                    case consts.line.NOLINE:
                        tmpList[0] = view.makeNodeLineClassEx(node) + newName;
                        break;
                    case consts.folder.OPEN:
                    case consts.folder.CLOSE:
                    case consts.folder.DOCU:
                    //小目录打开状态
                    case consts.folder.OPEN2:
                     //小目录关闭状态
                    case consts.folder.CLOSE2:
                        tmpList[1] = newName;
                        break;
                }
            replaceIcoClass: function (node, obj, newName) {
                if (!obj || node.isAjaxing) return;
                var tmpName = obj.attr("class");
                if (tmpName == undefined) return;
                var tmpList = tmpName.split("_");
                switch (newName) {
                    case consts.folder.OPEN:
                      //小目录打开状态
                    case consts.folder.OPEN2:
                      //小目录关闭状态
                    case consts.folder.CLOSE2:
                    case consts.folder.CLOSE:
                    case consts.folder.DOCU:
                        tmpList[tmpList.length - 1] = newName;
                        break;
                }
                obj.attr("class", tmpList.join("_"));
            },

更新节点的样式

做到这一步,已经完成了99%。最后一步就是修改css。准备好自己的背景图片,好像必须要求16x16的图片,大家自己尝试哈。
zTreeStyle.css文件中,修改原本的大目录css背景,添加自己的小目录背景

//大目录打开样式
.ztree li span.button.ico_open{margin-right:2px; background:url("./img/folder_open.png") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
//小目录打开样式
.ztree li span.button.ico_open2{margin-right:2px; background:url("./img/notepad_2.png") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
//文件样式
.ztree li span.button.ico_docu{margin-right:2px; background:url("./img/leaf.svg") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
//大目录关闭样式
.ztree li span.button.ico_close{margin-right:2px; background:url("./img/folder.png") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
//小目录关闭样式
.ztree li span.button.ico_close2{margin-right:2px; background:url("./img/notepad.png") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}

这个时候仅仅是替换完成了目录的样式,节点左侧的开关按钮css样式也要加上

.ztree li span.button.noline_open2{background-position:-92px -72px}
.ztree li span.button.noline_close2{background-position:-74px -72px}

最后展示效果如图所示:
ZTree自定义icon

提示:修改后的节点目录名称不能带”_”符号,否则会导致样式失败。原因在replaceIcoClassreplaceSwitchClass 方法里,有好奇心的同学请自己查看。