AI智能
改变未来

LayUi 树形组件tree 实现懒加载模式,异步加载子节点数据


本次重新star了官方最新tree.js源码,在其基础上扩展了子节点懒加载模式方法,data数据参数中增加了lazy: true,开启懒加载模式,需要配合spread事件使用。

<script>//初始化layui.use([\'tree\'], function () {var tree = layui.tree;//treeidvar inst1 = tree.render({elem: \'#treeid\',id: \'treeid\', //定义索引showCheckbox: true, //是否显示复选框showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。accordion: false, //是否开启手风琴模式,默认 falseonlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 falseisJump: false, //是否允许点击节点时弹出新窗口跳转。默认 falsedata: [{id: \'hg-100\',field: \'1\',level: \'1\',title: \'父节点100\',spread: true,children: [{id: \'hg-100101\',field: \'3\',level: \'2\',title: \'子节点100101\',children: [{id: \'hg-100101101\',field: \'4\',level: \'3\',title: \'子节点100101101\'}, {id: \'hg-100101102\',field: \'5\',level: \'3\',title: \'子节点100101102\'}, {id: \'hg-100101103\',field: \'6\',level: \'3\',title: \'子节点100101103\'}]}]}, {id: \'hg-200\',field: \'2\',level: \'1\',title: \'父节点200\',lazy: true}],text: {defaultNodeName: \'无数据\',none: \'加载数据失败!\'},click: function (obj) {console.log(obj.data); //得到当前点击的节点数据console.log(obj.state); //得到当前节点的展开状态:open、close、normalconsole.log(obj.elem); //得到当前节点元素console.log(obj.data.children); //当前节点下是否有子节点},oncheck: function (obj) {console.log(obj.data); //得到当前点击的节点数据console.log(obj.checked); //得到当前节点的展开状态:open、close、normalconsole.log(obj.elem); //得到当前节点元素},spread: function (obj) {console.log(obj);if(obj.state==\'open\'){setTimeout(() => {tree.lazytree(inst1.config.id, obj.elem, getTreeJson(obj.data.id));}, 2000);}}});//treeinputvar inst2;$(\"[name=\'dept\']\").on(\"click\",function (e) {e.stopPropagation();const deprt = this;if(!inst2){inst2 = tree.render({elem: \'#treeinputid\',id: \'treeinputid\', //定义索引showCheckbox: true, //是否显示复选框showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。accordion: false, //是否开启手风琴模式,默认 falseonlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 falseisJump: false, //是否允许点击节点时弹出新窗口跳转。默认 falsedata: [{id: \'hg-100\',field: \'1\',level: \'1\',title: \'父节点100\',spread: true,children: [{id: \'hg-100101\',field: \'3\',level: \'2\',title: \'子节点100101\',children: [{id: \'hg-100101101\',field: \'4\',level: \'3\',title: \'子节点100101101\'}, {id: \'hg-100101102\',field: \'5\',level: \'3\',title: \'子节点100101102\'}, {id: \'hg-100101103\',field: \'6\',level: \'3\',title: \'子节点100101103\'}]}]}, {id: \'hg-200\',field: \'2\',level: \'1\',title: \'父节点200\',lazy: true}],text: {defaultNodeName: \'无数据\',none: \'加载数据失败!\'},click: function (obj) {console.log(obj.data); //得到当前点击的节点数据console.log(obj.state); //得到当前节点的展开状态:open、close、normalconsole.log(obj.elem); //得到当前节点元素console.log(obj.data.children); //当前节点下是否有子节点},oncheck: function (obj) {var checkData = tree.getChecked(inst2.config.id);var map = getmap(checkData);$(deprt).val(map.value.join(\',\'));},spread: function (obj) {console.log(obj);if(obj.state==\'open\'){setTimeout(() => {tree.lazytree(inst2.config.id, obj.elem, getTreeJson(obj.data.id));}, 2000);}}});}$(\"#treeinputid\").toggle();})//监听表单提交事件hg.form.onsubmit(\'sreach\', function (data) {$(\"#treeinputid\").hide();var checkData = tree.getChecked(inst2.config.id);var map = getmap(checkData);var init = map.result;hg.msg(JSON.stringify(init));});const getmap = (target, result = []) => {layui.each(target,(i,e)=>{e.id && result.push({id:e.id,title:e.title});e.children && getmap(e.children, result);});let titles = result.map(e=>{return e.title});return {value:titles,result:result};};});// 模拟后台返回数据function getTreeJson(id) {if (id === \'hg-200\') {return [{id: \'hg-200101\',level: \'2\',title: \'子节点200101\'}, {id: \'hg-200102\',level: \'2\',title: \'子节点200102\',lazy: true}];}if (id === \'hg-200102\') {return [{id: \'hg-200102101\',level: \'3\',title: \'子节点200102101\'}, {id: \'hg-200102102\',level: \'3\',title: \'子节点200102102\',lazy: true}];}if (id === \'hg-200102102\') {return [{id: \'hg-200102102101\',level: \'4\',title: \'子节点200102102101\'}, {id: \'hg-200102102102\',level: \'4\',title: \'子节点200102102102\',}];}}//获得选中的节点function getChecked(){layui.use([\'tree\'], function () {var tree = layui.tree;var checkData = tree.getChecked(\'treeid\');hg.msg(JSON.stringify(checkData));});}//设置节点勾选function setChecked(){layui.use([\'tree\'], function () {var tree = layui.tree;tree.setChecked(\'treeid\', [\'hg-100101101\',\'hg-100101102\']);});}//实例重载function reload(){layui.use([\'tree\'], function () {var tree = layui.tree;tree.reload(\'treeid\', {});});}</script>

tree.js修改 完整版

/**@Name:layui.tree 树*/layui.define(\'form\', function(exports){\"use strict\";var $ = layui.$,form = layui.form,layer = layui.layer//模块名,MOD_NAME = \'tree\'//外部接口,tree = {config: {},index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0//设置全局项,set: function(options){var that = this;that.config = $.extend({}, that.config, options);return that;}//事件监听,on: function(events, callback){return layui.onevent.call(this, MOD_NAME, events, callback);}}//操作当前实例,thisModule = function(){var that = this,options = that.config,id = options.id || that.index;thisModule.that[id] = that; //记录当前实例对象thisModule.config[id] = options; //记录当前实例配置项return {config: options//重置实例,reload: function(options){that.reload.call(that, options);},getChecked: function(){return that.getChecked.call(that);},setChecked: function(id){//设置值return that.setChecked.call(that, id);},lazytree: function(elem, children){return that.tree.lazytree(that, elem, children);}}}//获取当前实例配置项,getThisModuleConfig = function(id){var config = thisModule.config[id];if(!config) hint.error(\'The ID option was not found in the \'+ MOD_NAME +\' instance\');return config || null;}//字符常量,SHOW = \'layui-show\', HIDE = \'layui-hide\', NONE = \'layui-none\', DISABLED = \'layui-disabled\',ELEM_VIEW = \'layui-tree\', ELEM_SET = \'layui-tree-set\', ICON_CLICK = \'layui-tree-iconClick\',ICON_ADD = \'layui-icon-addition\', ICON_SUB = \'layui-icon-subtraction\', ELEM_ENTRY = \'layui-tree-entry\', ELEM_MAIN = \'layui-tree-main\', ELEM_TEXT = \'layui-tree-txt\', ELEM_PACK = \'layui-tree-pack\', ELEM_SPREAD = \'layui-tree-spread\',ELEM_LINE_SHORT = \'layui-tree-setLineShort\', ELEM_SHOW = \'layui-tree-showLine\', ELEM_EXTEND = \'layui-tree-lineExtend\', ELEM_INIT = \'.layui-tree-init\'//构造器,Class = function(options){var that = this;that.index = ++tree.index;that.config = $.extend({}, that.config, tree.config, options);that.render();};//默认配置Class.prototype.config = {data: []  //数据,showCheckbox: false  //是否显示复选框,showLine: true  //是否开启连接线,accordion: false  //是否开启手风琴模式,onlyIconControl: false  //是否仅允许节点左侧图标控制展开收缩,isJump: false  //是否允许点击节点时弹出新窗口跳转,edit: false  //是否开启节点的操作图标,loading: true //请求数据时,是否显示loading,text: {defaultNodeName: \'未命名\' //节点默认名称,none: \'无数据\'  //数据为空时的文本提示}};//重载实例Class.prototype.reload = function(options){var that = this;layui.each(options, function(key, item){if(item.constructor === Array) delete that.config[key];});that.config = $.extend(true, {}, that.config, options);that.render();};//主体渲染Class.prototype.render = function(){var that = this,options = that.config;that.checkids = [];var temp = $(\'<div class=\"layui-tree\'+ (options.showCheckbox ? \" layui-form\" : \"\") + (options.showLine ? \" layui-tree-line\" : \"\") +\'\" lay-filter=\"LAY-tree-\'+ that.index +\'\"></div>\');options.loading && temp.attr(\'style\', \'padding-bottom: 15px;\');that.tree(temp);var othis = options.elem = $(options.elem);if(!othis[0]) return;//索引that.key = options.id || that.index;//插入组件结构that.elem = temp;that.elemNone = $(\'<div class=\"layui-tree-emptyText\">\'+ options.text.none +\'</div>\');othis.html(that.elem);if(that.elem.find(\'.layui-tree-set\').length == 0){return that.elem.append(that.elemNone);};//复选框渲染if(options.showCheckbox){that.renderForm(\'checkbox\');};that.elem.find(\'.layui-tree-set\').each(function(){var othis = $(this);//最外层if(!othis.parent(\'.layui-tree-pack\')[0]){othis.addClass(\'layui-tree-setHide\');};//没有下一个节点 上一层父级有延伸线if(!othis.next()[0] && othis.parents(\'.layui-tree-pack\').eq(1).hasClass(\'layui-tree-lineExtend\')){othis.addClass(ELEM_LINE_SHORT);};//没有下一个节点 外层最后一个if(!othis.next()[0] && !othis.parents(\'.layui-tree-set\').eq(0).next()[0]){othis.addClass(ELEM_LINE_SHORT);};});that.events();};//渲染表单Class.prototype.renderForm = function(type){form.render(type, \'LAY-tree-\'+ this.index);};//节点解析Class.prototype.tree = function(elem, children){var that = this,options = that.config,data = children || options.data;//遍历数据layui.each(data, function(index, item){var hasChild = item.children && item.children.length > 0,packDiv = $(\'<div class=\"layui-tree-pack\" \'+ (item.spread ? \'style=\"display: block;\"\' : \'\') +\'\"></div>\'),entryDiv = $([\'<div data-id=\"\'+ item.id +\'\" class=\"layui-tree-set\'+ (item.spread ? \" layui-tree-spread\" : \"\") + (item.checked ? \" layui-tree-checkedFirst\" : \"\") +\'\">\',\'<div class=\"layui-tree-entry\">\',\'<div class=\"layui-tree-main\">\'//箭头,function(){if(options.showLine){if(hasChild || item.lazy){ //lazy 是否开启懒加载,需要配合spread事件使用return \'<span class=\"layui-tree-iconClick layui-tree-icon\"><i class=\"layui-icon \'+ (item.spread ? \"layui-icon-subtraction\" : \"layui-icon-addition\") +\'\"></i></span>\';}else{return \'<span class=\"layui-tree-iconClick\"><i class=\"layui-icon layui-icon-file\"></i></span>\';};}else{return \'<span class=\"layui-tree-iconClick\"><i class=\"layui-tree-iconArrow \'+ (hasChild || item.lazy ? \"\": HIDE) +\'\"></i></span>\';};}()//复选框,function(){return options.showCheckbox ? \'<input type=\"checkbox\" name=\"\'+ (item.field || (\'layuiTreeCheck_\'+ item.id)) +\'\" same=\"layuiTreeCheck\" lay-skin=\"primary\" \'+ (item.disabled ? \"disabled\" : \"\") +\' value=\"\'+ item.id +\'\">\' : \'\';}()//节点,function(){if(options.isJump && item.href){return \'<a href=\"\'+ item.href +\'\" target=\"_blank\" class=\"\'+ ELEM_TEXT +\'\">\'+ (item.title || item.label || options.text.defaultNodeName) +\'</a>\';}else{return \'<span class=\"\'+ ELEM_TEXT + (item.disabled ? \' \'+ DISABLED : \'\') +\'\">\'+ (item.title || item.label || options.text.defaultNodeName) +\'</span>\';}}(),\'</div>\'//节点操作图标,function(){if(!options.edit) return \'\';var editIcon = {add: \'<i class=\"layui-icon layui-icon-add-1\"  data-type=\"add\"></i>\',update: \'<i class=\"layui-icon layui-icon-edit\" data-type=\"update\"></i>\',del: \'<i class=\"layui-icon layui-icon-delete\" data-type=\"del\"></i>\'}, arr = [\'<div class=\"layui-btn-group layui-tree-btnGroup\">\'];if(options.edit === true){options.edit = [\'update\', \'del\']}if(typeof options.edit === \'object\'){layui.each(options.edit, function(i, val){arr.push(editIcon[val] || \'\')});return arr.join(\'\') + \'</div>\';}}(),\'</div></div>\'].join(\'\'));//如果有子节点,则递归继续生成树if(hasChild){entryDiv.append(packDiv);that.tree(packDiv, item.children);};elem.append(entryDiv);//若有前置节点,前置节点加连接线if(entryDiv.prev(\'.\'+ELEM_SET)[0]){entryDiv.prev().children(\'.layui-tree-pack\').addClass(\'layui-tree-showLine\');};//若无子节点,则父节点加延伸线if(!hasChild){entryDiv.parent(\'.layui-tree-pack\').addClass(\'layui-tree-lineExtend\');};//展开节点操作that.spread(entryDiv, item);//选择框if(options.showCheckbox){item.checked && that.checkids.push(item.id);that.checkClick(entryDiv, item);}//操作节点options.edit && that.operate(entryDiv, item);});};//懒加载节点Class.prototype.lazytree = function(elem, children){var that = this,options = that.config,id = elem.attr(\'data-id\');var change = function(data){layui.each(data, function(index, e){if(e.id===id){data[index].children = children;return false;}if(e.children && e.children.length > 0){change(e.children);}});}//追加数据change(options.data);that.loading(elem, true);var packDiv = $(\'<div class=\"layui-tree-pack\"  style=\"display: block;\"></div>\');elem.append(packDiv);that.tree(packDiv, children);//复选框渲染if(options.showCheckbox){that.renderForm(\'checkbox\');};}//请求loadingClass.prototype.loading = function(elem, hide){var that = this,options = that.config;if(options.loading){if(hide){that.layInit && that.layInit.remove();delete that.layInit;that.elem.find(ELEM_INIT).remove();} else {that.layInit = $([\'<div class=\"layui-tree-init\">\',\'<i class=\"layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop\" style=\"position: absolute;left: 36px;\"></i>\',\'</div>\'].join(\'\'));elem.append(that.layInit);}}};//展开节点Class.prototype.spread = function(elem, item){var that = this,options = that.config,entry = elem.children(\'.\'+ELEM_ENTRY),elemMain = entry.children(\'.\'+ ELEM_MAIN),elemIcon = entry.find(\'.\'+ ICON_CLICK),elemText = entry.find(\'.\'+ ELEM_TEXT),touchOpen = options.onlyIconControl ? elemIcon : elemMain //判断展开通过节点还是箭头图标,state = \'\';//展开收缩touchOpen.on(\'click\', function(e){if(that.layInit) return false;var packCont = elem.children(\'.\'+ELEM_PACK),iconClick = touchOpen.children(\'.layui-icon\')[0] ? touchOpen.children(\'.layui-icon\') : touchOpen.find(\'.layui-tree-icon\').children(\'.layui-icon\');//若没有子节点if(!packCont[0]){state = \'normal\';}else{if(elem.hasClass(ELEM_SPREAD)){elem.removeClass(ELEM_SPREAD);packCont.slideUp(200);iconClick.removeClass(ICON_SUB).addClass(ICON_ADD);}else{elem.addClass(ELEM_SPREAD);packCont.slideDown(200);iconClick.addClass(ICON_SUB).removeClass(ICON_ADD);//是否手风琴if(options.accordion){var sibls = elem.siblings(\'.\'+ELEM_SET);sibls.removeClass(ELEM_SPREAD);sibls.children(\'.\'+ELEM_PACK).slideUp(200);sibls.find(\'.layui-tree-icon\').children(\'.layui-icon\').removeClass(ICON_SUB).addClass(ICON_ADD);};};};//展开产生的回调if(state===\'normal\' && item.lazy){var _spread = elem.hasClass(ELEM_SPREAD);if(elem.hasClass(ELEM_SPREAD)){elem.removeClass(ELEM_SPREAD);packCont.slideUp(200);iconClick.removeClass(ICON_SUB).addClass(ICON_ADD);}else{elem.addClass(ELEM_SPREAD);packCont.slideDown(200);iconClick.addClass(ICON_SUB).removeClass(ICON_ADD);//是否手风琴if(options.accordion){var sibls = elem.siblings(\'.\'+ELEM_SET);sibls.removeClass(ELEM_SPREAD);sibls.children(\'.\'+ELEM_PACK).slideUp(200);sibls.find(\'.layui-tree-icon\').children(\'.layui-icon\').removeClass(ICON_SUB).addClass(ICON_ADD);};};//判断展开收缩状态if(elem.hasClass(ELEM_SPREAD)){state = \'open\';} else {state = \'close\';}options.spread && options.spread({elem: elem,state: state,data: item});that.loading(elem);}});//点击回调elemText.on(\'click\', function(){var othis = $(this);//判断是否禁用状态if(othis.hasClass(DISABLED)) return;//判断展开收缩状态if(elem.hasClass(ELEM_SPREAD)){state = options.onlyIconControl ? \'open\' : \'close\';} else {state = options.onlyIconControl ? \'close\' : \'open\';}//点击产生的回调options.click && options.click({elem: elem,state: state,data: item});});};//计算复选框选中状态Class.prototype.setCheckbox = function(elem, item, elemCheckbox){var that = this,options = that.config,checked = elemCheckbox.prop(\'checked\');if(elemCheckbox.prop(\'disabled\')) return;//同步子节点选中状态if(typeof item.children === \'object\' || elem.find(\'.\'+ELEM_PACK)[0]){var childs = elem.find(\'.\'+ ELEM_PACK).find(\'input[same=\"layuiTreeCheck\"]\');childs.each(function(){if(this.disabled) return; //不可点击则跳过this.checked = checked;});};//同步父节点选中状态var setParentsChecked = function(thisNodeElem){//若无父节点,则终止递归if(!thisNodeElem.parents(\'.\'+ ELEM_SET)[0]) return;var state,parentPack = thisNodeElem.parent(\'.\'+ ELEM_PACK),parentNodeElem = parentPack.parent(),parentCheckbox =  parentPack.prev().find(\'input[same=\"layuiTreeCheck\"]\');//如果子节点有任意一条选中,则父节点为选中状态if(checked){parentCheckbox.prop(\'checked\', checked);} else { //如果当前节点取消选中,则根据计算“兄弟和子孙”节点选中状态,来同步父节点选中状态parentPack.find(\'input[same=\"layuiTreeCheck\"]\').each(function(){if(this.checked){state = true;}});//如果兄弟子孙节点全部未选中,则父节点也应为非选中状态state || parentCheckbox.prop(\'checked\', false);}//向父节点递归setParentsChecked(parentNodeElem);};setParentsChecked(elem);that.renderForm(\'checkbox\');};//复选框选择Class.prototype.checkClick = function(elem, item){var that = this,options = that.config,entry = elem.children(\'.\'+ ELEM_ENTRY),elemMain = entry.children(\'.\'+ ELEM_MAIN);//点击复选框elemMain.on(\'click\', \'input[same=\"layuiTreeCheck\"]+\', function(e){layui.stope(e); //阻止点击节点事件var elemCheckbox = $(this).prev(),checked = elemCheckbox.prop(\'checked\');if(elemCheckbox.prop(\'disabled\')) return;that.setCheckbox(elem, item, elemCheckbox);//复选框点击产生的回调options.oncheck && options.oncheck({elem: elem,checked: checked,data: item});});};//节点操作Class.prototype.operate = function(elem, item){var that = this,options = that.config,entry = elem.children(\'.\'+ ELEM_ENTRY),elemMain = entry.children(\'.\'+ ELEM_MAIN);entry.children(\'.layui-tree-btnGroup\').on(\'click\', \'.layui-icon\', function(e){layui.stope(e);  //阻止节点操作var type = $(this).data(\"type\"),packCont = elem.children(\'.\'+ELEM_PACK),returnObj = {data: item,type: type,elem:elem};//增加if(type == \'add\'){//若节点本身无子节点if(!packCont[0]){//若开启连接线,更改图标样式if(options.showLine){elemMain.find(\'.\'+ICON_CLICK).addClass(\'layui-tree-icon\');elemMain.find(\'.\'+ICON_CLICK).children(\'.layui-icon\').addClass(ICON_ADD).removeClass(\'layui-icon-file\');//若未开启连接线,显示箭头}else{elemMain.find(\'.layui-tree-iconArrow\').removeClass(HIDE);};//节点添加子节点容器elem.append(\'<div class=\"layui-tree-pack\"></div>\');};//新增节点var key = options.operate && options.operate(returnObj),obj = {};obj.title = options.text.defaultNodeName;obj.id = key;that.tree(elem.children(\'.\'+ELEM_PACK), [obj]);//放在新增后面,因为要对元素进行操作if(options.showLine){//节点本身无子节点if(!packCont[0]){//遍历兄弟节点,判断兄弟节点是否有子节点var siblings = elem.siblings(\'.\'+ELEM_SET), num = 1,parentPack = elem.parent(\'.\'+ELEM_PACK);layui.each(siblings, function(index, i){if(!$(i).children(\'.\'+ELEM_PACK)[0]){num = 0;};});//若兄弟节点都有子节点if(num == 1){//兄弟节点添加连接线siblings.children(\'.\'+ELEM_PACK).addClass(ELEM_SHOW);siblings.children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).removeClass(ELEM_LINE_SHORT);elem.children(\'.\'+ELEM_PACK).addClass(ELEM_SHOW);//父级移除延伸线parentPack.removeClass(ELEM_EXTEND);//同层节点最后一个更改线的状态parentPack.children(\'.\'+ELEM_SET).last().children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).last().addClass(ELEM_LINE_SHORT);}else{elem.children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).addClass(ELEM_LINE_SHORT);};}else{//添加延伸线if(!packCont.hasClass(ELEM_EXTEND)){packCont.addClass(ELEM_EXTEND);};//子节点添加延伸线elem.find(\'.\'+ELEM_PACK).each(function(){$(this).children(\'.\'+ELEM_SET).last().addClass(ELEM_LINE_SHORT);});//如果前一个节点有延伸线if(packCont.children(\'.\'+ELEM_SET).last().prev().hasClass(ELEM_LINE_SHORT)){packCont.children(\'.\'+ELEM_SET).last().prev().removeClass(ELEM_LINE_SHORT);}else{//若之前的没有,说明处于连接状态packCont.children(\'.\'+ELEM_SET).last().removeClass(ELEM_LINE_SHORT);};//若是最外层,要始终保持相连的状态if(!elem.parent(\'.\'+ELEM_PACK)[0] && elem.next()[0]){packCont.children(\'.\'+ELEM_SET).last().removeClass(ELEM_LINE_SHORT);};};};if(!options.showCheckbox) return;//若开启复选框,同步新增节点状态if(elemMain.find(\'input[same=\"layuiTreeCheck\"]\')[0].checked){var packLast = elem.children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).last();packLast.find(\'input[same=\"layuiTreeCheck\"]\')[0].checked = true;};that.renderForm(\'checkbox\');//修改}else if(type == \'update\'){var text = elemMain.children(\'.\'+ ELEM_TEXT).html();elemMain.children(\'.\'+ ELEM_TEXT).html(\'\');//添加输入框,覆盖在文字上方elemMain.append(\'<input type=\"text\" class=\"layui-tree-editInput\">\');//获取焦点elemMain.children(\'.layui-tree-editInput\').val(text).focus();//嵌入文字移除输入框var getVal = function(input){var textNew = input.val().trim();textNew = textNew ? textNew : options.text.defaultNodeName;input.remove();elemMain.children(\'.\'+ ELEM_TEXT).html(textNew);//同步数据returnObj.data.title = textNew;//节点修改的回调options.operate && options.operate(returnObj);};//失去焦点elemMain.children(\'.layui-tree-editInput\').blur(function(){getVal($(this));});//回车elemMain.children(\'.layui-tree-editInput\').on(\'keydown\', function(e){if(e.keyCode === 13){e.preventDefault();getVal($(this));};});//删除} else {layer.confirm(\'确认删除该节点 \"<span style=\"color: #999;\">\'+ (item.title || \'\') +\'</span>\" 吗?\', function(index){options.operate && options.operate(returnObj); //节点删除的回调returnObj.status = \'remove\'; //标注节点删除layer.close(index);//若删除最后一个,显示空数据提示if(!elem.prev(\'.\'+ELEM_SET)[0] && !elem.next(\'.\'+ELEM_SET)[0] && !elem.parent(\'.\'+ELEM_PACK)[0]){elem.remove();that.elem.append(that.elemNone);return;};//若有兄弟节点if(elem.siblings(\'.\'+ELEM_SET).children(\'.\'+ELEM_ENTRY)[0]){//若开启复选框if(options.showCheckbox){//若开启复选框,进行下步操作var elemDel = function(elem){//若无父结点,则不执行if(!elem.parents(\'.\'+ELEM_SET)[0]) return;var siblingTree = elem.siblings(\'.\'+ELEM_SET).children(\'.\'+ELEM_ENTRY),parentTree = elem.parent(\'.\'+ELEM_PACK).prev(),checkState = parentTree.find(\'input[same=\"layuiTreeCheck\"]\')[0],state = 1, num = 0;//若父节点未勾选if(checkState.checked == false){//遍历兄弟节点siblingTree.each(function(i, item1){var input = $(item1).find(\'input[same=\"layuiTreeCheck\"]\')[0]if(input.checked == false && !input.disabled){state = 0;};//判断是否全为不可勾选框if(!input.disabled){num = 1;};});//若有可勾选选择框并且已勾选if(state == 1 && num == 1){//勾选父节点checkState.checked = true;that.renderForm(\'checkbox\');//向上遍历祖先节点elemDel(parentTree.parent(\'.\'+ELEM_SET));};};};elemDel(elem);};//若开启连接线if(options.showLine){//遍历兄弟节点,判断兄弟节点是否有子节点var siblings = elem.siblings(\'.\'+ELEM_SET), num = 1,parentPack = elem.parent(\'.\'+ELEM_PACK);layui.each(siblings, function(index, i){if(!$(i).children(\'.\'+ELEM_PACK)[0]){num = 0;};});//若兄弟节点都有子节点if(num == 1){//若节点本身无子节点if(!packCont[0]){//父级去除延伸线,因为此时子节点里没有空节点parentPack.removeClass(ELEM_EXTEND);siblings.children(\'.\'+ELEM_PACK).addClass(ELEM_SHOW);siblings.children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).removeClass(ELEM_LINE_SHORT);};//若为最后一个节点if(!elem.next()[0]){elem.prev().children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).last().addClass(ELEM_LINE_SHORT);}else{parentPack.children(\'.\'+ELEM_SET).last().children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).last().addClass(ELEM_LINE_SHORT);};//若为最外层最后一个节点,去除前一个结点的连接线if(!elem.next()[0] && !elem.parents(\'.\'+ELEM_SET)[1] && !elem.parents(\'.\'+ELEM_SET).eq(0).next()[0]){elem.prev(\'.\'+ELEM_SET).addClass(ELEM_LINE_SHORT);};}else{//若为最后一个节点且有延伸线if(!elem.next()[0] && elem.hasClass(ELEM_LINE_SHORT)){elem.prev().addClass(ELEM_LINE_SHORT);};};};}else{//若无兄弟节点var prevDiv = elem.parent(\'.\'+ELEM_PACK).prev();//若开启了连接线if(options.showLine){prevDiv.find(\'.\'+ICON_CLICK).removeClass(\'layui-tree-icon\');prevDiv.find(\'.\'+ICON_CLICK).children(\'.layui-icon\').removeClass(ICON_SUB).addClass(\'layui-icon-file\');//父节点所在层添加延伸线var pare = prevDiv.parents(\'.\'+ELEM_PACK).eq(0);pare.addClass(ELEM_EXTEND);//兄弟节点最后子节点添加延伸线pare.children(\'.\'+ELEM_SET).each(function(){$(this).children(\'.\'+ELEM_PACK).children(\'.\'+ELEM_SET).last().addClass(ELEM_LINE_SHORT);});}else{//父节点隐藏箭头prevDiv.find(\'.layui-tree-iconArrow\').addClass(HIDE);};//移除展开属性elem.parents(\'.\'+ELEM_SET).eq(0).removeClass(ELEM_SPREAD);//移除节点容器elem.parent(\'.\'+ELEM_PACK).remove();};elem.remove();});};});};//部分事件Class.prototype.events = function(){var that = this,options = that.config,checkWarp = that.elem.find(\'.layui-tree-checkedFirst\');//初始选中that.setChecked(that.checkids);//搜索that.elem.find(\'.layui-tree-search\').on(\'keyup\', function(){var input = $(this),val = input.val(),pack = input.nextAll(),arr = [];//遍历所有的值pack.find(\'.\'+ ELEM_TEXT).each(function(){var entry = $(this).parents(\'.\'+ELEM_ENTRY);//若值匹配,加一个类以作标识if($(this).html().indexOf(val) != -1){arr.push($(this).parent());var select = function(div){div.addClass(\'layui-tree-searchShow\');//向上父节点渲染if(div.parent(\'.\'+ELEM_PACK)[0]){select(div.parent(\'.\'+ELEM_PACK).parent(\'.\'+ELEM_SET));};};select(entry.parent(\'.\'+ELEM_SET));};});//根据标志剔除pack.find(\'.\'+ELEM_ENTRY).each(function(){var parent = $(this).parent(\'.\'+ELEM_SET);if(!parent.hasClass(\'layui-tree-searchShow\')){parent.addClass(HIDE);};});if(pack.find(\'.layui-tree-searchShow\').length == 0){that.elem.append(that.elemNone);};//节点过滤的回调options.onsearch && options.onsearch({elem: arr});});//还原搜索初始状态that.elem.find(\'.layui-tree-search\').on(\'keydown\', function(){$(this).nextAll().find(\'.\'+ELEM_ENTRY).each(function(){var parent = $(this).parent(\'.\'+ELEM_SET);parent.removeClass(\'layui-tree-searchShow \'+ HIDE);});if($(\'.layui-tree-emptyText\')[0]) $(\'.layui-tree-emptyText\').remove();});};//得到选中节点Class.prototype.getChecked = function(){var that = this,options = that.config,checkId = [],checkData = [];//遍历节点找到选中索引that.elem.find(\'.layui-form-checked\').each(function(){checkId.push($(this).prev()[0].value);});//遍历节点var eachNodes = function(data, checkNode){layui.each(data, function(index, item){layui.each(checkId, function(index2, item2){if(item.id == item2){var cloneItem = $.extend({}, item);delete cloneItem.children;checkNode.push(cloneItem);if(item.children){cloneItem.children = [];eachNodes(item.children, cloneItem.children);}return true}});});};eachNodes($.extend({}, options.data), checkData);return checkData;};//设置选中节点Class.prototype.setChecked = function(checkedId){var that = this,options = that.config;//初始选中that.elem.find(\'.\'+ELEM_SET).each(function(i, item){var thisId = $(this).data(\'id\'),input = $(item).children(\'.\'+ELEM_ENTRY).find(\'input[same=\"layuiTreeCheck\"]\'),reInput = input.next();//若返回数字if(typeof checkedId === \'number\'){if(thisId == checkedId){if(!input[0].checked){reInput.click();};return false;};}//若返回数组else if(typeof checkedId === \'object\'){layui.each(checkedId, function(index, value){if(value == thisId && !input[0].checked){reInput.click();return true;}});};});};//记录所有实例thisModule.that = {}; //记录所有实例对象thisModule.config = {}; //记录所有实例配置项//重载实例tree.reload = function(id, options){var that = thisModule.that[id];that.reload(options);return thisModule.call(that);};//获得选中的节点数据tree.getChecked = function(id){var that = thisModule.that[id];return that.getChecked();};//设置选中节点tree.setChecked = function(id, checkedId){var that = thisModule.that[id];return that.setChecked(checkedId);};//懒加载增加节点tree.lazytree = function(id, elem, children){var that = thisModule.that[id];return that.lazytree(elem, children);};//核心入口tree.render = function(options){var inst = new Class(options);return thisModule.call(inst);};exports(MOD_NAME, tree);})
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » LayUi 树形组件tree 实现懒加载模式,异步加载子节点数据