LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据
LayUi框架中树形组件tree官方还在持续完善中,目前最新版本为v2.5.5
官方树形组件目前还不支持懒加载方式,之前我修改一版是通过reload重载实例方法填充子节点数据方式,因为递归页面元素时存在效率问题,最终放弃升级。
本次重新star了官方最新tree.js源码,在其基础上扩展了子节点懒加载模式方法,data数据参数中增加了lazy: true,开启懒加载模式,需要配合spread事件使用。
部分源码修改截图:
调用例子:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="hg-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="./css/font.css">
<link rel="stylesheet" href="../lib/layui/css/layui.css" media="all">
<link rel="stylesheet" href="./lib/admin/admin.css" media="all">
<link rel="stylesheet" href="./lib/Scrollbar/jquery.scrollbar.css">
<script type="text/javascript" src="./lib/admin/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="./lib/Scrollbar/jquery.scrollBar.js"></script>
<script type="text/javascript" src="./lib/layui/layui.js"></script>
<script type="text/javascript" src="./lib/admin/admin.js"></script>
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
.demo-tree{
width: 500px; height: 200px;
}
.demo-tree-box{
width: 500px; height: 200px;border: 1px #eee solid;overflow-y: auto;
}
.demo-input-tree{
height: auto;
width: 100%;
display: none;
position: absolute;
top: 100%;
background-color: #fff;
z-index: 100;
max-height: 400px;
}
.layui-input{
width: 500px;
cursor: pointer;
}
</style>
</head> <body class="layui-body-content">
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-form layui-card-header layui-card-header-auto">
<div class="layui-form-item">
<label class="layui-form-label">部门:</label>
<div class="layui-inline">
<input type="text" name="dept" lay-verify="required" placeholder="请选择部门" autocomplete="off" class="layui-input" readonly="true">
<div id="treeinputid" class="demo-input-tree demo-tree-box"></div>
</div>
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn layui-btn-lg layui-btn-normal" lay-submit lay-filter="sreach"><i
class="layui-icon layui-icon-lg"></i></button>
</div>
</div>
</div>
<div class="layui-card-body">
<div class="layui-card-header">
<button class="layui-btn layui-btn-lg layui-btn-normal"
onclick="getChecked()"><i
class="layui-icon"></i>获取选中</button>
<button class="layui-btn layui-btn-lg layui-btn-warm" onclick="setChecked()"><i
class="layui-icon"></i>设置节点勾选</button>
<button class="layui-btn layui-btn-lg layui-btn-danger" onclick="reload()"><i
class="layui-icon"></i>实例重载</button>
</div>
<div class="demo-tree">
<div id="treeid" class="demo-tree demo-tree-box"></div>
</div>
</div>
</div>
<div class="layui-floor">
<blockquote class="layui-elem-quote layui-quote-nm">Copyright©2019-2020, 本系统由@一如既往,提供技术支持!
</blockquote>
</div>
</div>
</body>
<script>
//初始化
layui.use(['tree'], function () {
var tree = layui.tree;
//treeid
var inst1 = tree.render({
elem: '#treeid',
id: 'treeid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
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、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
console.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);
}
}
}); //treeinput
var 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, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
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、normal
console.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> </html>
<script>
//初始化
layui.use(['tree'], function () {
var tree = layui.tree;
//treeid
var inst1 = tree.render({
elem: '#treeid',
id: 'treeid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
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、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
console.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);
}
}
}); //treeinput
var 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, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
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、normal
console.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>
【HG-Layui-UI通用后台管理框架V1.0版】
下载地址:
https://www.cnblogs.com/han1982/p/12003454.html
tree.js 下载地址在回复区可见。(layui-v2.5.5版本替换tree.js可用)
LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据的更多相关文章
- JQuery/JS插件 jsTree加载树,预先加载,初始化时加载前三级节点,当展开第三级节点时 就加载该节点下的所有子节点
jsTree加载树, 初始化时 加载前三级节点, 当展开第三级节点时 就加载该节点下的所有子节点 html: <!DOCTYPE html> <html> <head&g ...
- 修复使用<code>XmlDocument</code>加载含有DOCTYPE的Xml时,加载后增加“[]”字符的错误
C# LINQ TO XML - Remove “[]” characters from the DTD header http://stackoverflow.com/questions/12358 ...
- zTree设置异步加载后展开
//不能直接配置展开属性 因为没有数据,需要添加回调函数,异步加载成功展开 callback: { onAsyncSuccess: zTreeOnAsyncSuccess } //异步加载成功回调函数 ...
- 【EasyUI学习-2】Easyui Tree的异步加载
作者:ssslinppp 1. 摘要 2. tree的相关介绍 3. 异步加载tree数据,并实现tree的折叠展开 3.1 功能说明: 3.2 前台代码 3.3 后台代码 4. 其他 1 ...
- EasyUI之树形结构tree
转自:https://blog.csdn.net/ya_1249463314/article/details/70305730 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...
- 多线程异步加载图片async_pictures
异步加载图片 目标:在表格中异步加载网络图片 目的: 模拟 SDWebImage 基本功能实现 理解 SDWebImage 的底层实现机制 SDWebImage 是非常著名的网络图片处理框架,目前国内 ...
- ztree异步加载树节点
参考文档:https://www.cnblogs.com/tenWood/p/8620708.html ztree api地址:http://www.treejs.cn/v3/api.php 说明:j ...
- [翻译]Bitmap的异步加载和缓存
内容概述 [翻译]开发文档:android Bitmap的高效使用 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently", ...
- Jquery Ztree异步加载树
1. 下载jquery的JS文件/ztree的CSS文件和JS文件 https://jquery.com/download/ https://gitee.com/zTree/zTree_v3/tree ...
随机推荐
- 开源框架 openFrameworks
转自:https://www.cnblogs.com/lidabo/p/9134174.html 此处仅供学习,版权属原作者: 作为一个图形图像方向的研究生,我经常都在和 OpenGL .OpenCV ...
- 智能家居手势识别,只需百度AI即可搞定
上次我尝试做了一个给眼镜加特效,针对的是静态图像,具体文章参考 https://ai.baidu.com/forum/topic/show/942890 . 这次我尝试在视频中加眼镜特效,并且加上手势 ...
- 平时常用sql
总结一下平时用到最多的sql语句 1.特殊日期 --今天凌晨 ,) --明天凌晨 ,,) --当周周一(每周从周日开始) ,) --当月的第一天 ,) --当月的最后一天 ,,,)) --今年的第一天 ...
- 报错解决 unable to unroll loop, loop does not appear to terminate in a timely manner (994 iterations) or unrolled loop is too large, use the [unroll(n)] attribute to force an exact higher number
在 Unity 写 Shader 的时候,在一个循环里面使用了 tex2D 函数,类似与下面这样: fixed2 center = fixed2(0.5,0.5); fixed2 uv = i.uv ...
- ASP.NET Core 2.x 到 3.1 迁移指南
一.前言 今日(2019/12/4).NET Core 3.1 正式发布了,ASP.NET Core 3.1 随之发布,这次 3.0 到 3.1经过了两个月的短周期,并没有增加重大的功能,主要是对 3 ...
- 转载 SAP用户权限控制设置及开发
创建用户SU01 事务码:SU01,用户主数据的维护,可以创建.修改.删除.锁定.解锁.修改密码等 缺省:可以设置用户的起始菜单.登录的默认语言.数字显示格式.以及日期和时间的格式设置 参数:SAP很 ...
- CAD怎么算面积?这种方法你要知道
在CAD中,打开可能都是用过CAD制图软件,这是一个比较强大的绘图软件,可以绘制出各种类型的CAD图纸文件,还可以将绘制好的图纸面积进行测量.那CAD怎么算面积?其实计算面积的方法有很多中,下面给大家 ...
- MySQL Aborted_clients和 Aborted_connects状态变量详解
Aborted_clients和 Aborted_connects状态变量详解 By:授客 QQ:1033553122 状态变量定义 Aborted_clients 因客户端消亡时未恰当的关闭连接 ...
- 修改so库中的依赖名
修改so库中的依赖名 在ArchLinuxArm上有一些针对aarch64, arm, armeabi-v7a等Android常用架构的so库可以下载,有时候可以省去很多编译时间,且都是编译optim ...
- Android 程序分析环境搭建-动态分析环境搭建
静态查看过app 的代码,但是有些app 非常复杂,页面好多,你根本找不到从何处下手.还有app 通过静态分析,发现有被加固(后续会讲如何砸壳),根本找不到,还有即便你搜索app界面上的文字,你也搜索 ...