架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 291|回复: 0

[JavaScript] JS--插件: 树Tree 开发与实现 附件可下载!!

[复制链接]
跳转到指定楼层
楼主
发表于 2019-7-11 11:20:12
本帖最后由 szxiaxiaojun 于 2019-7-11 11:20 编辑

日常在Web项目开发时,经常会碰到树形架构数据的显示,从数据库中获取数据,并且显示成树形。为了方便,我们可以写一个javascript的一个跨浏览器树控件,后续可以重复使用。本节分享一个自己开发的JS tree插件,对有需要的朋友可以直接下载使用。
   Tree插件 需要实现
       (1)、自动将数据组织成上下级关系,这样我们在前端手工添加数据或者从数据库中获取到的数据不需要我们来组织上下级关系
       (2)、支持自定 加载目录树  支持XML、JSON 格式的数据加载
       (3)、实现树节点的选择(单选、复选[级联选择])功能
       (4)、支持大数据的一次性加载
       。。。。。。
   下面开始分享自己写的一个Tree 插件:  此插件基于Jquery  需要引用

    第一:插件中每个树节点Node的参数JSON对象如下所示
            nodeItem: function () {
                return {
                    nodecode: "",             //  节点编码
                    nodetext: "",               //  节点文本 [节点显示文本]
                    nodetitle: "",               //  节点标题 [用于鼠标移过时显示的节点文本]
                    supnodecode: "",       //  上级节点编码 [定义此节点所属的上级节点编码,通过此编码来组成上下级关系]
                    nodeurl: "",                 //  节点URL 表示当前节点自定的链接URL地址
                    iconexpand: "",           //  节点展开图标 [目录树节点自定展开状态下显示的图标,如果为空,则采用默认的图标]
                    iconcollapse: ""          //  节点收缩图标 [目录树节点自定收缩状态下显示的图标,如果为空,则采用默认的图标]
                }
            }
     第二:加载目录树的三种方法
             1、loadJson(Json)             JSON 对象目录树节点数组(一次性完成)
                                                       JSON 格式 是一个Array 数组  每项为一个 nodeItem 对象的参数
                                                       [
                                                            {   nodecode: "", nodetext: "", nodetitle: "",supnodecode: "",nodeurl: "",iconexpand: "" ,iconcollapse: "" },
                                                            {},...
                                                       ]

             2、loadXml(xml)                 XML字符串格式的节点数据(一次性完成)
                                                        说明:采用XML字符串格式  注意节点 tagName:nodecode nodetext 等 不允许变更 因为程序内部是直接采用这个名字来获取的         
                                                       <root>
                                                             <item>   //  每一个节点 内包含多个数据值   
                                                                  <nodecode><![CDATA[节点编码值]]></nodecode>     
                                                                  <nodetext><![CDATA[节点名称文本 ]]></nodetext>
                                                                  <nodetitle><![CDATA[节点鼠标移入显示提示文本]]></nodetitle>
                                                                  <supnodecode><![CDATA[节点所属上级即父节点编码]]></supnodecode>
                                                                  <nodeurl><![CDATA[节点关联链接地址]]></nodeurl>
                                                                  <iconexpand><![CDATA[节点展开时显示图标路径]]></iconexpand>   
                                                                  <iconcollapse><![CDATA[节点收缩时显示图标路径]]></iconcollapse>   
                                                            </item>
                                                            ... ...
                                                        </root>

             3、通过插件对象 的方法   addNodeItem(nodeItem)      通过手工一条一条的添加节点项目(需要两步完成) 全部添加完成后
                                                      通过插件对象 makeTree()    再手工调用此方法,则可以创建树

      第三:目录树内部重组上下级关系的事件方法  通过此方法,可以解决我们前端不再需要按照上下级关系来区分。
  1. _createTree: function () {    // 创建树HTML对象
  2.                     // 初始化变量参数
  3.                     this._sdpTree.empty();       // 清空目录树内的所有内容
  4.                     this._fnObject.focusNodeCode = "";
  5.                     this._myNodes = [];
  6.                     this._hsNodes = new $.Hashtable();
  7.                     this._dtNodes = [];
  8.                     var _tmNodes = [], F = this._fnObject, P = this._fnObject.options, _this = this;

  9.                     // 重组目录节点(依次将所有的节点组成自己的树) 一次循环完成 提高效率
  10.                     function Renew_GroupNodes(currNodes) {
  11.                         // 重绘节点上下级关系
  12.                         function Renew_Tree(reNode) {
  13.                             if (_tmNodes[reNode.nodecode]) {
  14.                                 for (var n = 0; n < _tmNodes[reNode.nodecode].length; n++) {
  15.                                     reNode._childs[n] = _tmNodes[reNode.nodecode][n];
  16.                                     reNode._childs[n]._parent = reNode;
  17.                                     reNode._childs[n]._firstFlag = (n == 0) ? true : false;
  18.                                     reNode._childs[n]._lastFlag = (n == (_tmNodes[reNode.nodecode].length - 1)) ? true : false;
  19.                                     reNode._childs[n]._haveChild = (_tmNodes[_tmNodes[reNode.nodecode][n].nodecode]) ? true : false;
  20.                                     reNode._childs[n]._nodeLevel = reNode._nodeLevel + 1;
  21.                                     Renew_Tree(_tmNodes[reNode.nodecode][n]);  // 迭代循环
  22.                                 }
  23.                             }
  24.                         };

  25.                         var m = 0;
  26.                         _tmNodes[P.rootcode] = [];   // 根节点
  27.                         for (m = 0; m < currNodes.length; m++) {
  28.                             var _nd = currNodes[m];
  29.                             _tmNodes[_nd.supnodecode] = _tmNodes[_nd.supnodecode] || [];
  30.                             _tmNodes[_nd.supnodecode].push(_nd);
  31.                             _this._hsNodes.add(_nd.nodecode, _nd);
  32.                         };
  33.                         var _rtNodes = _tmNodes[P.rootcode];

  34.                         for (m = 0; m < _rtNodes.length; m++) {
  35.                             _this._dtNodes[m] = _rtNodes[m];
  36.                             _this._dtNodes[m]._parent = null;
  37.                             _this._dtNodes[m]._firstFlag = (m == 0) ? true : false;  // 设置参数
  38.                             _this._dtNodes[m]._lastFlag = (m == (_rtNodes.length - 1)) ? true : false;
  39.                             _this._dtNodes[m]._haveChild = (_tmNodes[_rtNodes[m].nodecode]) ? true : false;
  40.                             _this._dtNodes[m]._nodeLevel = 1;
  41.                             Renew_Tree(_rtNodes[m]);                               // 迭代循环
  42.                         };

  43.                         _rtNodes = null;
  44.                         _tmNodes = null;
  45.                     };

  46.                     // 执行节点重组
  47.                     Renew_GroupNodes(F.curNodes);
  48.                     F.curNodes = [];  // 清空临时节点数组变量,便于后续重新加载使用

  49.                     // 定义前缀字符
  50.                     var full_Prefix = this._myFnId + "_sdptree_node_full";     // 完整的一个节点DIV(包含:连线、+号图片、节点图片、选择框、节点文本)
  51.                     var node_Prefix = this._myFnId + "_sdptree_node_span";     // 节点SPAN
  52.                     // var plus_Prefix = this._myFnId + "_sdptree_node_plus";     // + 号图片
  53.                     var nimg_Prefix = this._myFnId + "_sdptree_node_icon";     // 节点图片
  54.                     var chkr_Prefix = this._myFnId + "_sdptree_node_chk";      // 选择图片
  55.                     var text_Prefix = this._myFnId + "_sdptree_node_text";     // 节点文本
  56.                     var clip_Prefix = this._myFnId + "_sdptree_node_clip";     // 子节点DIV

  57.                     // 注意点:前台传入的所有自定义的图标,全部已经是指定的完整路径了,所以这里就不需要转换
  58.                     var _rootCode = P.rootcode;
  59.                     if (P.showroot) {           // 判定是否显示根节点
  60.                         var tmRhtml = [];
  61.                         tmRhtml.push('<div id="' + full_Prefix + '_' + _rootCode + '" stype="full" >');
  62.                         tmRhtml.push('<span id="' + node_Prefix + '_' + _rootCode + '" class="node_default" stype="node" >');
  63.                         if (P.showicon) {
  64.                             tmRhtml.push('<span id="' + nimg_Prefix + '_' + _rootCode + '" stype="icon" ');
  65.                             if (P.rooticon) {   // 是否客户自定义的图片
  66.                                 tmRhtml.push('class="custom_img" style="background-image: url(' + (P.rooticon) + ');"');
  67.                             } else {                                // 启用默认的样式图片
  68.                                 tmRhtml.push('class="root_img"');
  69.                             };
  70.                             tmRhtml.push(' ></span>');
  71.                         };
  72.                         if (P.selecttype == "checkbox") {     // 是否开启选择按钮
  73.                             tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="checkbox"></span>');
  74.                         } else if (P.selecttype == "radio") {
  75.                             tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="radiobtn"></span>');
  76.                         };
  77.                         tmRhtml.push('<span id="' + text_Prefix + '_' + _rootCode + '"  class="root_title" stype="text">' + P.roottext + '</span>');
  78.                         tmRhtml.push('</span>');
  79.                         tmRhtml.push('</div>');
  80.                         this._sdpTree.append($(tmRhtml.join("")));
  81.                         tmRhtml = null;
  82.                     };
  83.                     var $clipDom = null;
  84.                     if (P.showroot) $clipDom = $('<div id="' + clip_Prefix + '_' + _rootCode + '" class="clipdiv" stype="clip" style="display: block" ></div>');
  85.                     var _recHTML = this._createNodes(this._dtNodes);
  86.                     if (_recHTML) {
  87.                         if ($clipDom) { $clipDom.append($(_recHTML)); this._sdpTree.append($clipDom); } else { this._sdpTree.append($(_recHTML)); };
  88.                     } else {
  89.                         if ($clipDom) { this._sdpTree.append($clipDom); };
  90.                     };
  91.                     _recHTML = null;

  92.                     // 绑定事件
  93.                     this._bindEvent();
  94.                     if (P.openall) { F.expandAll(); };
  95.                 },
复制代码
第四:以上只是简单的介绍了一下Tree的主要加载和重组方法。下面我们将完整的JS插件代码贴出来,代码中有详细的注释
                  插件功能:复选、单选、展开、折叠、显示/隐藏节点连线 、支持插入节点、删除节点、节点小图标自定义、设置节点选中、获取目录树选择节点(支持XML,JSON等)
                                  右击菜单(暂时不支持,因为需要用到弹出层,这里就屏蔽删除了此功能)  支持节点单击、双击、节点选择改变事件等等
最终显示效果
附件下载:
Tree_Demo.rar (54.71 KB, 下载次数: 0)




上一篇:从Hadoop HDFS中直接下载文件
下一篇:Git 忽略提交 .gitignore
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-10-21 14:34

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表