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 ...
随机推荐
- Android 自定义吐司通知
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV ...
- 蒟蒻的PKUWC2019划水记(更新ing)
前言 (结束再补) \(Dec\ 20th\) 正式出发 今天,是正式出发的日子. 虽说是星期五,可并没有去学校晨跑.难得睡到了\(7\)点,起来匆匆吃完了早饭(一个手抓饼),就出发去火车站了. 到了 ...
- Splash 学习笔记
一.介绍 Splash 跟之前我们介绍的 Selenium ( 参考 Selenium 与自动化测试 -- <Selenium 2 自动化测试实战>读书笔记) 很类似,都可以理解成一个浏览 ...
- VScode - 10个提高工作效率的快捷键
复制行 shift + alt + up / down 移动行 alt + up / down 多选 按住alt + 鼠标单击 删除上个单词 ctrl + Backspace 全部保存 ctrl + ...
- Complete_NGINX_Cookbook
Complete NGINX Cookbook 下载地址:Complete NGINX Cookbook
- Android studio 3.4 新建项目报错Error:unable to resolve dependency for app@。。。解决办法
试过网上很多的例子,有的设置Go to `File->Settings->Build, Execution, Deployment->Gradle->Uncheck Offli ...
- Zstack的安装部署
ZStack是下一代开源的云计算IaaS(基础架构即服务)软件. 它主要面向的是未来的智能数据中心,通过提供全完善的API来管理包括计算.存储和网络在内的数据中心的各种资源.跟OpenStack相比, ...
- [转载]——Automatic Tuning of Undo_retention Causes Space Problems (文档 ID 420525.1)
Automatic Tuning of Undo_retention Causes Space Problems (文档 ID 420525.1) 转到底部 In this Document Sy ...
- InnoDB On-Disk Structures(四)--Doublewrite Buffer (转载)
转载.节选于 https://dev.mysql.com/doc/refman/8.0/en/innodb-doublewrite-buffer.html The doublewrite buffer ...
- How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 394798.1)
How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 39479 ...