LayUI Treeコンポーネント拡張機能の実装(検索機能、チェックボックス、カスタムノードアイコン、右クリックメニュー)(ソースコード付き)

最近、プロジェクトオプションのフロントエンドテクノロジーの選択にLayUIが選択されました。選択されなかったのは、ツリーコンポーネントの機能が弱すぎるということでした。私はそれをしませんでした。ソースコードを自分で変更する必要がありました。現在、次の機能が実装されています。githubで更新する時間がないので、しばらくお待ちください。次に、拡張関数を見てみましょう。

1.拡張機能

1.ディレクトリツリーの検索機能を追加しました

2.ディレクトリツリーにチェックボックスとイベントコールバックの実現を追加

3.ルートノードアイコンとリーフアイコンのカスタム設定を追加しました。

4.右クリックメニューとイベントコールバックを追加しました。

私のお母さんにレンダリングを見てもらいましょう

検索の実装
検索機能効果

 

    

右クリックメニュー
右クリックメニューの実装

 

二つ、実装のソースコードを見てみましょう

   メソッドを呼び出す

layui.use(['tree', 'layer'], function () {
			var layer = layui.layer
				, $ = layui.jquery
				, tree = layui.tree;

			// 同步(绑定)layui的tree的搜索(过滤)框
			// treeId: tree所在的容器的id
			// filter: 对应的搜索框的selector或者dom对象,尽量要确保是唯一的节点,或者真的是要控制这个树的input
			// callback: 回调 参数(树节点jquery对象, 输入框对象, 匹配到的节点数量)
			tree.syncLayuiTreeFilter = function (treeId, filter, callback) {
				var treeElem = $('#' + treeId), filterElem = $(filter);
				if (!filterElem.length || !filterElem.length) {
					return;
				}
				filterElem.keyup(
					function (event) {
						var that = this;
						var value = $(that).val().trim().toLocaleLowerCase();//不区分大小写
						var HIDE = 'layui-hide';
						var hintClass = 'search_hit';
						// 先恢复现场
						treeElem.find('.' + HIDE).removeClass(HIDE);
						treeElem.find('.' + hintClass).removeClass(hintClass).each(function (index, item) {
							item = $(item);
							item.html(item.data('textOld')).data('textOld', null);
						});
						// 如果有值筛选开始
						if (value) {
							layui.each(treeElem.find('cite'), function (index, elem) {
								elem = $(elem);
								var textTemp = elem.text();
								if (textTemp.toLocaleLowerCase().indexOf(value) === -1) {  //不区分大小写
									// 不存在就隐藏
									elem.closest('li').addClass(HIDE);
								} else {
									// 命中就添加一个class
									elem.addClass(hintClass)
										.data('textOld', textTemp)
										.html(textTemp.replace(new RegExp(value, 'g'), '<span class="search_hint_text">' + value + '</span>'));
								}
							});
							layui.each(treeElem.find('.' + hintClass), function (index, elem) {
								elem = $(elem);
								elem.parents('li').removeClass(HIDE);
								elem.parents('ul').each(function (i, item) {
									if (!$(item).hasClass('layui-show')) {
										$(item).parent('li').find('>i').click();
									}
								});
								elem.parents('ul').parent('li').removeClass(HIDE);
							});
						}
						typeof callback === 'function' && callback.call(that, treeElem, filterElem, treeElem.find('.' + hintClass).length);
					}
				);
			};

			tree({
				elem: '#layTree' //指定元素
				,branchExtent:["Ico_fold","Ico_launch"] //树形折叠图标第一个是折叠样式,第二个展开样式
				,target: '_blank' //是否新选项卡打开(比如节点返回href才有效)
				,check: 'checkbox'
				,checkboxName: 'ck'//复选框的name属性值
				,checkboxStyle: ""
				,drag: true
				, nodes: [ //节点
					{
						name: '常用文件夹'
						,id: 1
						,alias: 'changyong'
						,checked: true
						,data:{
							text:123,//data-text 用于存储数据
							ceshi:456}
						, children: [
							{
								name: '所有未读'
								, id: 11
								, href: 'http://www.layui.com/'
								, alias: 'weidu'
								, checked: true
								,leaf:"Ico_point1" //css样式
								,data:{}
							},
							{
								name: '置顶邮件'
								,id: 12
								,leaf:"Ico_point2"
								,data:{}
							}, {
								name: '邮件标签邮件'
								,id: 13
								,leaf:"Ico_point3"
								,data:{}
								,children: [
									{
										name: '所有未读'
										, id: 11
										, href: 'http://www.layui.com/'
										, alias: 'weidu'
										, checked: true
										, leaf:"Ico_point1" //css样式
										,data:{}
									},
									{
										name: '置顶邮件'
										,id: 12
										,leaf:"Ico_point2"
										,data:{}
									}, {
										name: '邮件标签邮件'
										,id: 13
										,leaf:"Ico_point3"
										,data:{}
									}
								]
							}
						]
					}
				]
				,click: function(node){
					console.log(node) //node即为当前点击的节点数据
                    var as= $("#layTree").find('a');
					$.each(as,function (index,obj) {
					    if($(obj).children("cite").text()=='置顶邮件') {

					        console.log($(obj).parent());
                            $(obj).parent().append("<ul class=\"layui-show\"><li><i style=\"paddling-left: 28px;\"></i><input type=\"checkbox\" name=\"ck\" checked=\"checked\" data-parent-id=\"lyn_1554703113157_1_3_lel\" id=\"lyn_1554703113158_3_5_nly\"><a href=\"http://www.layui.com/\" target=\"_blank\"><i class=\"layui-icon Ico_point1\"></i><cite>所有未读</cite></a></li><li><i style=\"paddling-left: 28px;\"></i><input type=\"checkbox\" name=\"ck\" data-parent-id=\"lyn_1554703113157_1_3_lel\" id=\"lyn_1554703113160_5_7_nayryl\"><a href=\"javascript:;\" class=\"\"><i class=\"layui-icon Ico_point2\"></i><cite>置顶邮件</cite></a></li><li><i class=\"layui-icon layui-tree-spread\"></i><input type=\"checkbox\" name=\"ck\" data-parent-id=\"lyn_1554703113157_1_3_lel\" id=\"lyn_1554703113160_7_9_ney\"><a href=\"javascript:;\"><i class=\"layui-icon Ico_fold\"></i><cite>邮件标签邮件</cite></a><ul class=\"\"><li><i style=\"paddling-left: 28px;\"></i><input type=\"checkbox\" name=\"ck\" checked=\"checked\" data-parent-id=\"lyn_1554703113160_7_9_ney\" id=\"lyn_1554703113161_9_11_aa\"><a href=\"http://www.layui.com/\" target=\"_blank\"><i class=\"layui-icon Ico_point1\"></i><cite>所有未读</cite></a></li><li><i style=\"paddling-left: 28px;\"></i><input type=\"checkbox\" name=\"ck\" data-parent-id=\"lyn_1554703113160_7_9_ney\" id=\"lyn_1554703113161_11_13_lrl\"><a href=\"javascript:;\"><i class=\"layui-icon Ico_point2\"></i><cite>置顶邮件</cite></a></li><li><i style=\"paddling-left: 28px;\"></i><input type=\"checkbox\" name=\"ck\" data-parent-id=\"lyn_1554703113160_7_9_ney\" id=\"lyn_1554703113162_13_15_e\"><a href=\"javascript:;\"><i class=\"layui-icon Ico_point3\"></i><cite>邮件标签邮件</cite></a></li></ul></li></ul>");

                             //element.init();
                           // tree.render();
					        return false;
                        }

                    })
				},
				onchange: function (event,item){//当当前input发生变化后所执行的回调
					console.log(item); //item即为当前点击的节点数据
					console.log(event); //事件源
				}
				,rightClick:function(event,elem) {
					console.log("你的鼠标右击了我!"+elem);
					console.log(elem);
					event.preventDefault();
					return false;
				}
			});

			tree.syncLayuiTreeFilter('layTree', '[name="searchTree"]', function (treeElem, filterElem, hitNumbers) {
				console.log('hitNumbers', hitNumbers);
				layer.msg('找到' + hitNumbers + '个节点');
			});

  tree.jsソースコード

//扩展日志  author:wangxianyang
//1,增加复选框并且加上了事件回调和参数传递
//2,增加了折叠图标和叶子图标的自定义扩展
//3,增加了右击菜单事件和参数传递
//4,增加了tree的搜索功能(模糊匹配不区分大小写)
;
layui.define("jquery",
    function(e) {
      "use strict";
      var o = layui.jquery,
          a = layui.hint(),
          r = "layui-tree-enter",
          i = function(e) {
            this.options = e
          },
          t = {
            arrow: ["&#xe623;", "&#xe625;"],
            checkbox: ["&#xe626;", "&#xe627;"],
            radio: ["&#xe62b;", "&#xe62a;"],
            branch: ["&#xe622;", "&#xe624;"],
            leaf: "&#xe621;"
          },
          branchExtent,//折叠图标扩展
          leafExtent="",//叶子图标扩展
          leftClick=true,
          num = 1;
      i.prototype.init = function(e) {
        var o = this;
        branchExtent=o.options.branchExtent||["",""];
        e.addClass("layui-box layui-tree"),
        o.options.skin && e.addClass("layui-tree-skin-" + o.options.skin),
            o.tree(e),
            o.on(e)
        //e.preventDefault();
        false;
      },
          i.prototype.tree = function(e, a) {
            var r = this,
                i = r.options,
                n = a || i.nodes;
            layui.each(n,
                function(a, n) {
                  var id = r.uuid();
                  n.id = id;
                  //console.log(n.data);
                  if (n.children) {
                    layui.each(n.children,
                        function(index, item) {
                          item.pid = n.id;
                        });
                  }
                  var l = n.children && n.children.length > 0,
                      c = o('<ul class="' + (n.spread ? "layui-show": "") + '"></ul>'),
                      s = o(["<li " + (n.spread ? 'data-spread="' + n.spread + '"': "") + ">",
                        function() {
                          return l ? '<i class="layui-icon layui-tree-spread">' + (n.spread ? t.arrow[1] : t.arrow[0]) + '</i>': '<i style="paddling-left: 28px;"></i>';
                        } (),
                        function() {
                          var eleStr = i.check && i.check == "checkbox" ? '<input type="checkbox" name="' + i.checkboxName + '" ' + ((n.checked && n.checked == true) ? 'checked="checked"': "") + (n.checkboxValue ? ('value="' + n.checkboxValue + '"') : "") + 'data-parent-id="' + n.pid + '"' + 'id="' + n.id + '"' + (i.checkboxStyle ? (' style="' + i.checkboxStyle + '"') : "") : '';
                          if (eleStr.length > 0) {
                            if (n.data && Object.prototype.toString.call(n.data) == "[object Object]") {
                              for (var attr in n.data) {
                                eleStr += ' data-' + attr + '=' + n.data[attr];
                              }
                            }
                            eleStr += ' />';
                          }
                          return eleStr;
                        } (),
                        function() {
                          //debugger;
                          //return '<a href="' + (n.href || "javascript:;") + '" ' + (i.target && n.href ? 'target="' + i.target + '"': "") + ">" + ('<i class="layui-icon layui-tree-' + (l ? "branch": "leaf") + '">' + (l ? n.spread ? t.branch[1] : t.branch[0] : t.leaf) + "</i>") + ("<cite>" + (n.name || "未命名") + "</cite></a>")
                          return '<a href="' + (n.href || "javascript:;") + '" '
                              + (i.target && n.href ? 'target="' + i.target + '"': "") + ">"
                              + ('<i class="layui-icon ' + (l ? n.spread ? branchExtent[1] : branchExtent[0] : n.leaf) + '">'
                                  + "</i>") + ("<cite>" + (n.name || "未命名") + "</cite></a>")
                        } (), "</li>"].join(""));

                  l && (s.append(c), r.tree(c, n.children)),e.append(s), "function" == typeof i.click && r.click(s, n),r.spread(s, n), i.drag && r.drag(s, n) , i.onchange && r.changed(s, n)   //注册复选框事件
                })
          },
          i.prototype.changed = function(e, o) {
            var r = this;
            if (o.pid == undefined || o.pid == null) {
              e.children("input").on("change",
                  function() {
                    var childUl = e.children("ul"),
                        checked = this.checked;
                    childUl.find("input").prop("checked", checked);
                    try {
                      // debugger;
                      r.options.onchange((e.children("input").prop("checked") || false), o);
                    } catch(e) {}
                  });
            } else {
              e.children("input").on("change",
                  function() {
                    var that = this;
                    if (!this.checked) {
                      childCheckboxCheckOrNot.call(this);
                      r.cancelParentsCheckboxCheck(that);
                    } else {
                      r.parentsChecked(this, this.checked);
                      childCheckboxCheckOrNot.call(this);
                    }
                    try {
                      //debugger;
                      r.options.onchange((e.children("input").prop("checked") || false), o);
                    } catch(e) {}
                  });
            }
            function childCheckboxCheckOrNot() {
              if (o.children && o.children.length > 0) {
                var childUl = e.children("ul"),
                    checked = this.checked;
                childUl.find("input").prop("checked", checked);
              }
            }
          },
          i.prototype.cancelParentsCheckboxCheck = function(ele) {
            if (!ele) {
              return;
            }
            var r = this,
                siblingInputs = r.siblingInputs(ele),
                parentId = ele.getAttribute("data-parent-id"),
                parentInput = null,
                bool = true,
                childrendInputs = null,
                hasOneChildrenInputCheck = false;
            if (parentId != 'undefined') {
              parentInput = document.getElementById(parentId);
              childrendInputs = r.currentChildrenInputs(parentInput);
            }
            for (var i = 0,
                     len = siblingInputs.length; i < len; i++) {
              if (siblingInputs[i].checked) {
                bool = false;
                break;
              }
            }
            if (!childrendInputs || childrendInputs.length == 0) {
              hasOneChildrenInputCheck = false;
            } else {
              for (var j = 0,
                       len2 = childrendInputs.length; j < len2; j++) {
                if (childrendInputs[j].getAttribute("data-parent-id") != "undefined") {
                  if (childrendInputs[j].checked) {
                    hasOneChildrenInputCheck = true;
                    break;
                  }
                }
              }
            }
            if (bool && !hasOneChildrenInputCheck) {
              r.inputChecked(parentInput, false);
            }
            this.cancelParentsCheckboxCheck(parentInput);
          },
          i.prototype.siblingInputs = function(ele) {
            var that = this;
            if (ele) {
              var parent = ele.parentElement,
                  parents = parent.parentElement,
                  childrens = parents.children,
                  siblingInputs = [];
            } else {
              return null;
            }
            for (var i = 0,
                     len = childrens.length; i < len; i++) {
              if (childrens[i] != parent) {
                if (childrens[i].children[0].nodeName == "INPUT") {
                  siblingInputs.push(childrens[i].children[0]);
                }
                if (childrens[i].children[1].nodeName == "INPUT") {
                  siblingInputs.push(childrens[i].children[1]);
                }
              }
            }
            parent = null;
            parents = null;
            childrens = null;
            return siblingInputs;
          },
          i.prototype.currentChildrenInputs = function(ele) {
            var parent = ele.parentElement,
                childrenInputs = [];
            if (parent.getElementsByTagName("ul").length > 0) {
              var uls = parent.getElementsByTagName("ul");
              for (var i = 0,
                       len = uls.length; i < len; i++) {
                var inputs = uls[i].getElementsByTagName("input");
                for (var j = 0,
                         len2 = inputs.length; j < len2; j++) {
                  childrenInputs.push(inputs[j]);
                }
              }
            }
            return childrenInputs;
          },
          i.prototype.inputChecked = function(ele, checked) {
            ele && (ele.checked = checked);
          },
          i.prototype.parentsChecked = function(e, checked) {
            var r = this,
                i = r.options,
                selector = i.elem,
                currentInput = e;
            if (currentInput && (currentInput.nodeName == "INPUT")) {
              var parentId = currentInput.getAttribute("data-parent-id"),
                  parentInput = null;
              setTimeout(function() {
                    r.inputChecked(currentInput, checked);
                    if (parentId) {
                      r.parentsChecked(document.getElementById(parentId), checked);
                    }
                  },
                  50);
            }
          },
          i.prototype.findParents = function(ele, selector) {
            var parent = ele.parentElement,
                that = this;
            if (selector.substr(0, 1) == "#") {
              if (parent) {
                if (parent.id != selector.substr(1)) {
                  that.findParents(parent, selector);
                } else {
                  return parent;
                }
              }
            } else if (selector.substr(0, 1) == ".") {
              if (parent) {
                var classnameArr = parent.className.split(" "),
                    len = classnameArr.length,
                    selectt = selector.substr(1),
                    hasSelector = false;
                if (len > 0) {
                  for (var i = 0; i < len; i++) {
                    if (classnameArr[i] == selectt) {
                      hasSelector = true;
                      break;
                    }
                  }
                }
                if (!hasSelector) {
                  that.findParents(parent, selector);
                } else if (hasSelector) {
                  return parent;
                }
              }
            }
          },
          i.prototype.uuid = function() {
            var that = this,
                randomStr = ['l', 'a', 'y', 'e', 'r', 'n', 'i'],
                randomNum = Math.floor(Math.random() * 6);
            return function() {
              var str = "";
              for (var i = 0; i <= randomNum; i++) {
                str += randomStr[Math.floor(Math.random() * 6)];
              }
              return "lyn_" + new Date().getTime() + "_" + (num++) + "_" + (++num) + "_" + str;
            } ();
          },
          i.prototype.click = function(e, o) {
            var a = this,
                r = a.options;
            e.children("a").on("click",
                function(e) {
                  //debugger;
                  layui.stope(e),
                      r.click(o)
                })
          },
          i.prototype.spread = function(e, o) {
            //debugger;
            var a = this,
                r = (a.options, e.children(".layui-tree-spread")),
                i = e.children("ul"),
                n = e.children("a"),
                l = function() {
                  e.data("spread") ? (e.data("spread", null), i.removeClass("layui-show"), r.html(t.arrow[0]),

                      n.find(".layui-icon").removeClass(branchExtent[1]).addClass(branchExtent[0])) : (e.data("spread", !0), i.addClass("layui-show"), r.html(t.arrow[1]), n.find(".layui-icon").removeClass(branchExtent[0]).addClass(branchExtent[1]))
                };
            i[0] && (r.on("click", l), n.on("dblclick", l))
          },

          //n.find(".layui-icon").html(t.branchExtent[0])):(e.data("spread",!0),i.addClass("layui-show"),r.html(t.arrow[1]),
          //n.find(".layui-icon").html(t.branchExtent[1]))};i[0]&&(r.on("click",l),n.on("dblclick",l))},
          i.prototype.on = function(e) {
            var a = this,
                i = a.options,
                t = "layui-tree-drag";
            e.find("i").on("selectstart",
                function(e) {
                  return ! 1
                }),
            i.drag && o(document).on("mousemove",
                function(e) {
                  var r = a.move;
                  if (r.from) {
                    var i = (r.to, o('<div class="layui-box ' + t + '"></div>'));
                    e.preventDefault(),
                    o("." + t)[0] || o("body").append(i);
                    var n = o("." + t)[0] ? o("." + t) : i;
                    n.addClass("layui-show").html(r.from.elem.children("a").html()),
                        n.css({
                          left: e.pageX + 10,
                          top: e.pageY + 10
                        })
                  }
                }).on("mouseup",
                function(ev) {
                  var ee = a.move;


                  if(ee.from && ee.from.elem && ee.from.elem[0]){
                    //自定义鼠标右击事件
                    //debugger;
                    ee.from.elem[0].oncontextmenu = function(){
                      //debugger;
                      if(!leftClick){leftClick=true;}
                      if(typeof i.rightClick=="function" ){
                        var oEvent=ev.event;
                        if (!oEvent) oEvent=window.event;
                        if (oEvent.button==2) {
                          try { //debugger;
                            leftClick=!leftClick;
                            if(!leftClick)
                            {
                              layui.stope(e);
                              i.rightClick(a,ee);
                              //leftClick=false;
                            }
                          } catch(e) {}
                          oEvent.stopPropagation();
                          oEvent.preventDefault();
                          return false;
                        }
                      }
                    }
                  }

                  ee.from && (ee.from.elem.children("a").removeClass(r), ee.to && ee.to.elem.children("a").removeClass(r), a.move = {},
                      o("." + t).remove());
                  ev.preventDefault();
                  return false;
                })
          },
          i.prototype.move = {},
          i.prototype.drag = function(e, a) {
            var i = this,
                t = (i.options, e.children("a")),
                n = function() {
                  var t = o(this),
                      n = i.move;
                  n.from && (n.to = {
                    item: a,
                    elem: e
                  },
                      t.addClass(r))
                };
            t.on("mousedown",
                function() {
                  var o = i.move;
                  o.from = {
                    item: a,
                    elem: e
                  }
                }),
                t.on("mouseenter", n).on("mousemove", n).on("mouseleave",
                    function() {
                      var e = o(this),
                          a = i.move;
                      a.from && (delete a.to, e.removeClass(r))
                    })
          },
          e("tree",
              function(e) {
                var r = new i(e = e || {}),
                    t = o(e.elem);
                return t[0] ? void r.init(t) : a.error("layui.tree 没有找到" + e.elem + "元素");
              })
    })

3つ以上

それでも質問を伝える必要がある場合は、

それでも分からない場合は

ツリーのバックグラウンドコードをビルドするために.NETバージョンが必要な場合は、

ツリーのバックグラウンドコードをビルドするためにJAVAバージョンが必要な場合は、

一緒に勉強して話し合いましょう。........

私たちの拠点に参加できます。拠点の住所は450342630(QQグループ番号)です。

おすすめ

転載: blog.csdn.net/qq_27532167/article/details/89139039
おすすめ