Implementación de la extensión del componente LayUI Tree (función de búsqueda, casilla de verificación, icono de nodo personalizado, menú contextual) (con código fuente)

Recientemente, LayUI fue seleccionado para la selección de tecnología de front-end de la opción del proyecto. Lo que no se seleccionó fue que la función del componente de árbol era demasiado débil. No lo hice. Tuve que modificar el código fuente yo mismo. Las siguientes funciones están implementadas actualmente. No hay tiempo para actualizar en github, así que estad atentos . Entonces echemos un vistazo a las funciones extendidas:

1. Funciones ampliadas

1. Se agregó la función de búsqueda del árbol de directorios.

2. Se agregó la realización de casillas de verificación y devoluciones de llamada de eventos en el árbol del directorio.

3. Se agregaron configuraciones personalizadas para el icono del nodo raíz y el icono de la hoja.

4. Se agregó el menú contextual y la devolución de llamada del evento.

Deja que mi mamá eche un vistazo a las representaciones.

Implementación de búsqueda
Efecto de la función de búsqueda

 

    

Menú contextual
Implementación del menú contextual

 

Dos, déjame ver el código fuente de implementación

   Método de llamada

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 + '个节点');
			});

  código fuente de 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 + "元素");
              })
    })

Tres más

Si aún necesita comunicar preguntas,

Si aún no lo entiende,

Si necesita la versión .NET para construir el código de fondo del árbol,

Si necesita la versión JAVA para construir el código de fondo del árbol,

Estudiemos y discutamos juntos. ........

Puede unirse a nuestra base, la dirección de nuestra base es: 450342630 (número de grupo QQ)

Supongo que te gusta

Origin blog.csdn.net/qq_27532167/article/details/89139039
Recomendado
Clasificación