diff --git a/cff/echartsTheme.js b/cff/echartsTheme.js deleted file mode 100644 index 3254a73..0000000 --- a/cff/echartsTheme.js +++ /dev/null @@ -1,515 +0,0 @@ -layui.define(function(exports) { // 定义一个模块,使用layui的模块化机制 - exports('echartsTheme', // 导出名为'echartsTheme'的模块 - { - "color": [ // 设置图表的颜色数组 - "#3fb1e3", // 蓝色 - "#6be6c1", // 绿色 - "#626c91", // 深蓝色 - "#a0a7e6", // 浅蓝色 - "#c4ebad", // 浅绿色 - "#96dee8" // 浅蓝色 - ], - "backgroundColor": "rgba(252,252,252,0)", // 设置背景颜色为透明白色 - "textStyle": {}, // 文本样式,此处为空对象表示默认样式 - "title": { // 标题样式配置 - "textStyle": { // 主标题样式 - "color": "#666666" // 主标题颜色为灰色 - }, - "subtextStyle": { // 副标题样式 - "color": "#999999" // 副标题颜色为浅灰色 - } - }, - "line": { - // 设置线条的样式 - "itemStyle": { - // 正常状态下的样式 - "normal": { - // 边框宽度为3 - "borderWidth": "3" - } - }, - // 设置线条的样式 - "lineStyle": { - // 正常状态下的样式 - "normal": { - // 线宽为4 - "width": "4" - } - }, - // 设置符号的大小为10 - "symbolSize": "10", - // 设置符号的形状为空圆 - "symbol": "emptyCircle", - // 启用平滑曲线 - "smooth": true - }, - "radar": { - // 设置雷达图的样式 - "itemStyle": { - // 正常状态下的样式 - "normal": { - // 边框宽度为3 - "borderWidth": "3" - } - }, - // 设置线条样式 - "lineStyle": { - // 正常状态下的线条样式 - "normal": { - // 线条宽度为4 - "width": "4" - } - }, - // 设置符号大小 - "symbolSize": "10", - // 设置符号类型为空心圆 - "symbol": "emptyCircle", - // 设置曲线平滑 - "smooth": true - }, - // 设置柱状图样式 - "bar": { - // 设置项目样式 - "itemStyle": { - // 正常状态下的柱状图样式 - "normal": { - // 柱状图边框宽度为0 - "barBorderWidth": 0, - // 柱状图边框颜色为#ccc - "barBorderColor": "#ccc" - }, - // 强调状态下的柱状图样式 - "emphasis": { - // 柱状图边框宽度为0 - "barBorderWidth": 0, - // 柱状图边框颜色为#ccc - "barBorderColor": "#ccc" - } - } - } - "pie": { // 饼图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "scatter": { // 散点图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "boxplot": { // 箱线图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "parallel": { // 平行坐标系配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - } - "sankey": { // 桑基图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "funnel": { // 漏斗图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "gauge": { // 仪表盘配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - }, - "emphasis": { // 强调状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色(#ccc) - } - } - }, - "candlestick": { // 定义K线图样式 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "color": "#e6a0d2", // K线图颜色为粉红色 - "color0": "transparent", // 下跌部分的颜色为透明 - "borderColor": "#e6a0d2", // 边框颜色为粉红色 - "borderColor0": "#3fb1e3", // 下跌部分的边框颜色为蓝色 - "borderWidth": "2" // 边框宽度为2 - } - } - }, - "graph": { // 定义关系图样式 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "borderWidth": 0, // 边框宽度为0 - "borderColor": "#ccc" // 边框颜色为灰色 - } - }, - "lineStyle": { // 线条样式配置 - "normal": { // 正常状态下的样式 - "width": "1", // 线条宽度为1 - "color": "#cccccc" // 线条颜色为浅灰色 - } - }, - "symbolSize": "10", // 节点大小为10 - "symbol": "emptyCircle", // 节点形状为空心圆 - "smooth": true, // 是否平滑曲线 - "color": [ // 节点颜色数组 - "#3fb1e3", // 第一个颜色为蓝色 - "#6be6c1", // 第二个颜色为绿色 - "#626c91", // 第三个颜色为深蓝色 - "#a0a7e6", // 第四个颜色为淡蓝色 - "#c4ebad", // 第五个颜色为淡绿色 - "#96dee8" // 第六个颜色为浅蓝色 - ], - "label": { // 标签样式配置 - "normal": { // 正常状态下的样式 - "textStyle": { // 文本样式配置 - "color": "#ffffff" // 文本颜色为白色 - } - } - } - } - }, - "map": { // 地图配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "areaColor": "#eeeeee", // 区域颜色为浅灰色(#eeeeee) - "borderColor": "#aaaaaa", // 边框颜色为中灰色(#aaaaaa) - "borderWidth": 0.5 // 边框宽度为0.5 - }, - "emphasis": { // 强调状态下的样式 - "areaColor": "rgba(63,177,227,0.25)", // 区域颜色为半透明蓝色(rgba(63,177,227,0.25)) - "borderColor": "#3fb1e3", // 边框颜色为蓝色(#3fb1e3) - "borderWidth": 1 // 边框宽度为1 - } - }, - "label": { // 标签配置项 - "normal": { // 正常状态下的标签样式 - "textStyle": { // 文本样式 - "color": "#ffffff" // 文本颜色为白色(#ffffff) - } - }, - "emphasis": { // 强调状态下的标签样式 - "textStyle": { // 文本样式 - "color": "rgb(63,177,227)" // 文本颜色为蓝色(rgb(63,177,227)) - } - } - } - }, - "geo": { // 地理坐标系组件配置项 - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "areaColor": "#eeeeee", // 区域颜色为浅灰色(#eeeeee) - "borderColor": "#aaaaaa", // 边框颜色为中灰色(#aaaaaa) - "borderWidth": 0.5 // 边框宽度为0.5 - }, - "emphasis": { // 强调状态下的样式 - "areaColor": "rgba(63,177,227,0.25)", // 区域颜色为半透明蓝色(rgba(63,177,227,0.25)) - "borderColor": "#3fb1e3", // 边框颜色为蓝色(#3fb1e3) - "borderWidth": 1 // 边框宽度为1 - } - } - } "label": { // 标签配置项 - "normal": { // 正常状态下的样式 - "textStyle": { // 文本样式 - "color": "#ffffff" // 文本颜色为白色(#ffffff) - } - }, - "emphasis": { // 强调状态下的样式 - "textStyle": { // 文本样式 - "color": "rgb(63,177,227)" // 文本颜色为蓝色(rgb(63,177,227)) - } - } - } - }, - "categoryAxis": { // 类目轴配置项 - "axisLine": { // 轴线配置 - "show": true, // 显示轴线 - "lineStyle": { // 线条样式 - "color": "#cccccc" // 轴线颜色为浅灰色(#cccccc) - } - }, - "axisTick": { // 刻度线配置 - "show": false, // 不显示刻度线 - "lineStyle": { // 线条样式 - "color": "#333" // 刻度线颜色为深灰色(#333) - } - }, - "axisLabel": { // 轴标签配置 - "show": true, // 显示轴标签 - "textStyle": { // 文本样式 - "color": "#999999" // 轴标签颜色为浅灰色(#999999) - } - }, - "splitLine": { // 分隔线配置 - "show": true, // 显示分隔线 - "lineStyle": { // 线条样式 - "color": [ // 分隔线颜色数组 - "#eeeeee" // 分隔线颜色为浅灰色(#eeeeee) - ] - } - }, - "splitArea": { // 分隔区域配置项 - "show": false, // 是否显示分隔区域,默认为false - "areaStyle": { // 分隔区域的样式配置 - "color": [ // 分隔区域的颜色数组 - "rgba(250,250,250,0.05)", // 第一个颜色值,半透明白色 - "rgba(200,200,200,0.02)" // 第二个颜色值,半透明灰色 - ] - } - }, - "valueAxis": { // 数值轴配置项 - "axisLine": { // 轴线配置 - "show": true, // 是否显示轴线,默认为true - "lineStyle": { // 轴线的样式配置 - "color": "#cccccc" // 轴线的颜色,灰色 - } - }, - "axisTick": { // 刻度线配置 - "show": false, // 是否显示刻度线,默认为false - "lineStyle": { // 刻度线的样式配置 - "color": "#333" // 刻度线的颜色,深灰色 - } - }, - "axisLabel": { // 轴标签配置 - "show": true, // 是否显示轴标签,默认为true - "textStyle": { // 轴标签文本的样式配置 - "color": "#999999" // 轴标签文本的颜色,浅灰色 - } - }, - "splitLine": { // 分隔线配置 - "show": true, // 是否显示分隔线,默认为true - "lineStyle": { // 分隔线的样式配置 - "color": [ // 分隔线的颜色数组 - "#eeeeee" // 分隔线的颜色,浅灰色 - ] - } - }, - "splitArea": { // 配置图表的分隔区域 - "show": false, // 是否显示分隔区域,这里设置为不显示 - "areaStyle": { // 分隔区域的样式设置 - "color": [ // 分隔区域的颜色数组 - "rgba(250,250,250,0.05)", // 第一个颜色值,半透明白色 - "rgba(200,200,200,0.02)" // 第二个颜色值,半透明灰色 - ] - } - }, - "logAxis": { // 对数轴的配置 - "axisLine": { // 坐标轴线的配置 - "show": true, // 是否显示坐标轴线,这里设置为显示 - "lineStyle": { // 坐标轴线的样式设置 - "color": "#cccccc" // 坐标轴线的颜色,设置为浅灰色 - } - }, - "axisTick": { // 坐标轴刻度的配置 - "show": false, // 是否显示坐标轴刻度,这里设置为不显示 - "lineStyle": { // 坐标轴刻度的样式设置 - "color": "#333" // 坐标轴刻度的颜色,设置为深灰色 - } - }, - "axisLabel": { // 坐标轴标签的配置 - "show": true, // 是否显示坐标轴标签,这里设置为显示 - "textStyle": { // 坐标轴标签文本的样式设置 - "color": "#999999" // 坐标轴标签文本的颜色,设置为浅灰色 - } - }, - "splitLine": { // 分隔线的设置 - "show": true, // 是否显示分隔线,这里设置为显示 - "lineStyle": { // 分隔线的样式设置 - "color": [ // 分隔线的颜色数组 - "#eeeeee" // 分隔线的颜色,设置为浅灰色 - ] - } - }, - "splitArea": { // 分隔区域配置项 - "show": false, // 是否显示分隔区域,默认为false - "areaStyle": { // 分隔区域的样式配置 - "color": [ // 分隔区域的颜色数组 - "rgba(250,250,250,0.05)", // 第一个颜色值,半透明白色 - "rgba(200,200,200,0.02)" // 第二个颜色值,半透明灰色 - ] - } - }, - "timeAxis": { // 时间轴配置项 - "axisLine": { // 轴线配置 - "show": true, // 是否显示轴线,默认为true - "lineStyle": { // 轴线的样式配置 - "color": "#cccccc" // 轴线的颜色,灰色 - } - }, - "axisTick": { // 刻度线配置 - "show": false, // 是否显示刻度线,默认为false - "lineStyle": { // 刻度线的样式配置 - "color": "#333" // 刻度线的颜色,深灰色 - } - }, - "axisLabel": { // 标签配置 - "show": true, // 是否显示标签,默认为true - "textStyle": { // 标签文本的样式配置 - "color": "#999999" // 标签文本的颜色,浅灰色 - } - }, - "splitLine": { // 分隔线配置 - "show": true, // 是否显示分隔线,默认为true - "lineStyle": { // 分隔线的样式配置 - "color": [ // 分隔线的颜色数组 - "#eeeeee" // 分隔线的颜色,浅灰色 - ] - } - }, - "splitArea": { // 分隔区域配置项 - "show": false, // 是否显示分隔区域,默认为false - "areaStyle": { // 分隔区域的样式配置 - "color": [ // 分隔区域的颜色数组 - "rgba(250,250,250,0.05)", // 第一个颜色值,半透明白色 - "rgba(200,200,200,0.02)" // 第二个颜色值,半透明灰色 - ] - } - }, - "toolbox": { // 工具箱配置项 - "iconStyle": { // 图标样式配置 - "normal": { // 正常状态下的样式 - "borderColor": "#999999" // 边框颜色为深灰色(#999999) - }, - "emphasis": { // 强调状态下的样式 - "borderColor": "#666666" // 边框颜色为中灰色(#666666) - } - } - }, - "legend": { // 图例配置项 - "textStyle": { // 文本样式配置 - "color": "#999999" // 文本颜色为深灰色(#999999) - } - }, - "tooltip": { // 提示框配置项 - "axisPointer": { // 坐标轴指示器配置 - "lineStyle": { // 线条样式配置 - "color": "#cccccc", // 线条颜色为浅灰色(#cccccc) - "width": 1 // 线条宽度为1 - }, - "crossStyle": { // 十字准星样式配置 - "color": "#cccccc", // 颜色为浅灰色(#cccccc) - "width": 1 // 宽度为1 - } - } - }, - "timeline": { // 时间轴配置项 - "lineStyle": { // 轴线样式配置 - "color": "#626c91", // 轴线颜色,深蓝色 - "width": 1 // 轴线宽度为1 - }, - "itemStyle": { // 项目样式配置 - "normal": { // 正常状态下的样式 - "color": "#626c91", // 项目颜色,深蓝色 - "borderWidth": 1 // 边框宽度为1 - }, - "emphasis": { // 强调状态下的样式 - "color": "#626c91" // 强调状态下的项目颜色,深蓝色 - } - }, - "controlStyle": { // 控制按钮样式配置 - "normal": { // 正常状态下的样式 - "color": "#626c91", // 控制按钮颜色,深蓝色 - "borderColor": "#626c91", // 控制按钮边框颜色,深蓝色 - "borderWidth": 0.5 // 控制按钮边框宽度为0.5 - }, - "emphasis": { // 强调状态下的样式 - "color": "#626c91", // 强调状态下的控制按钮颜色,深蓝色 - "borderColor": "#626c91", // 强调状态下的控制按钮边框颜色,深蓝色 - "borderWidth": 0.5 // 强调状态下的控制按钮边框宽度为0.5 - } - }, - "checkpointStyle": { // 检查点样式配置 - "color": "#3fb1e3", // 检查点颜色,浅蓝色 - "borderColor": "rgba(63,177,227,0.15)" // 检查点边框颜色,半透明浅蓝色 - }, - "label": { // 标签样式配置 - "normal": { // 正常状态下的标签样式 - "textStyle": { // 文本样式配置 - "color": "#626c91" // 标签文本颜色,深蓝色 - } - }, - "emphasis": { // 强调状态下的标签样式 - "textStyle": { // 文本样式配置 - "color": "#626c91" // 强调状态下的标签文本颜色,深蓝色 - } - } - } - }, - "visualMap": { // 视觉映射组件配置项 - "color": [ // 颜色数组,用于定义视觉映射的颜色范围 - "#2a99c9", // 起始颜色,蓝色 - "#afe8ff" // 结束颜色,浅蓝色 - ] - }, - "dataZoom": { // 数据区域缩放组件配置项 - "backgroundColor": "rgba(255,255,255,0)", // 背景颜色,完全透明 - "dataBackgroundColor": "rgba(222,222,222,1)", // 数据区域的背景颜色,灰色 - "fillerColor": "rgba(114,230,212,0.25)", // 填充颜色,半透明的绿色 - "handleColor": "#cccccc", // 手柄颜色,灰色 - "handleSize": "100%", // 手柄大小,占满容器 - "textStyle": { // 文本样式配置 - "color": "#999999" // 文本颜色,深灰色 - } - }, - "markPoint": { // 标记点组件配置项 - "label": { // 标签配置 - "normal": { // 正常状态下的标签样式 - "textStyle": { // 文本样式 - "color": "#ffffff" // 文本颜色,白色 - } - }, - "emphasis": { // 强调状态下的标签样式 - "textStyle": { // 文本样式 - "color": "#ffffff" // 文本颜色,白色 - } - } - } - } - }); // 结束配置对象 - }); // 结束函数调用 \ No newline at end of file diff --git a/cff/miniAdmin.js b/cff/miniAdmin.js deleted file mode 100644 index 622ade4..0000000 --- a/cff/miniAdmin.js +++ /dev/null @@ -1,450 +0,0 @@ -layui.define(["jquery", "miniMenu", "element","miniPage", "miniTheme","axios","store"], function (exports) { // 定义一个模块,依赖列表包括 jQuery, miniMenu, element, miniPage, miniTheme, axios, store - var $ = layui.$, // 获取 jQuery 模块并赋值给变量 $ - element = layui.element, // 获取 element 模块并赋值给变量 element - layer = layui.layer, // 获取 layer 模块并赋值给变量 layer - miniMenu = layui.miniMenu, // 获取 miniMenu 模块并赋值给变量 miniMenu - miniTheme = layui.miniTheme, // 获取 miniTheme 模块并赋值给变量 miniTheme - store = layui.store, // 获取 store 模块并赋值给变量 store - axios = layui.axios, // 获取 axios 模块并赋值给变量 axios - miniPage = layui.miniPage; - - if (!/http(s*):\/\//.test(location.href)) { // 检查当前页面的URL是否以http或https开头,如果不是则执行以下代码块 - var tips = "请先将项目部署至web容器(Apache/Tomcat/Nginx/IIS/等),否则部分数据将无法显示"; // 定义提示信息,告知用户需要将项目部署到Web容器中 - return layer.alert(tips); // 使用layer.alert方法弹出提示框,显示上述提示信息,并终止后续代码的执行 - } - - var miniAdmin = { // 定义一个名为miniAdmin的对象,用于存放后续的代码逻辑和功能实现 - - - render: function (options) { - options.iniUrl = options.iniUrl || null; // 初始化URL,默认为null - options.logoInfo = options.logoInfo || null; // Logo信息,默认为null - options.homeInfo = options.homeInfo || null; // 首页信息,默认为null - options.clearUrl = options.clearUrl || null; // 清除URL,默认为null - options.renderPageVersion = options.renderPageVersion || false; // 是否渲染页面版本,默认为false - options.bgColorDefault = options.bgColorDefault || 0; // 默认背景颜色,默认为0 - options.multiModule = options.multiModule || false; // 是否支持多模块,默认为false - options.menuChildOpen = options.menuChildOpen || false; // 菜单子项是否默认展开,默认为false - options.loadingTime = options.loadingTime || 1; // 加载时间,默认为1秒 - options.pageAnim = options.pageAnim || false; // 页面动画效果,默认为false - } - - // 使用axios发送GET请求获取初始化数据 - axios.get(options.iniUrl).then(function (data) { - // 如果返回的数据为空,显示错误信息 - if (data == null) { - miniAdmin.error('暂无菜单信息') - } else { - // 渲染logo信息 - miniAdmin.renderLogo(options.logoInfo); - // 渲染清除按钮 - miniAdmin.renderClear(options.clearUrl); - // 渲染页面动画效果 - miniAdmin.renderAnim(options.pageAnim); - // 监听并处理首页信息和多模块信息 - miniAdmin.listen({ - // 监听homeInfo属性,并传递options对象中的homeInfo值 - homeInfo: options.homeInfo, - // 监听multiModule属性,并传递options对象中的multiModule值 - multiModule: options.multiModule, - }) - miniMenu.render({ - // 将数据列表传递给菜单渲染函数 - menuList: data.data, - // 传递是否支持多模块的选项 - multiModule: options.multiModule, - // 传递子菜单默认打开状态的选项 - menuChildOpen: options.menuChildOpen - }); - miniPage.render({ - // 设置首页信息,从options对象中获取homeInfo属性 - homeInfo: options.homeInfo, - // 设置菜单列表数据,从data对象的data属性中获取 - menuList: data.data, - // 设置是否启用多模块功能,从options对象中获取multiModule属性 - multiModule: options.multiModule, - // 设置页面渲染版本,从options对象中获取renderPageVersion属性 - renderPageVersion: options.renderPageVersion, - // 设置子菜单是否默认打开,从options对象中获取menuChildOpen属性 - menuChildOpen: options.menuChildOpen, - // 定义监听切换回调函数,当触发时调用miniAdmin的renderDevice方法 - listenSwichCallback: function () { - miniAdmin.renderDevice(); - } - }); - miniTheme.render({ - // 设置默认背景颜色 - bgColorDefault: options.bgColorDefault, - // 监听事件 - listen: true, - }); - // 删除加载器,传入加载时间参数 - miniAdmin.deleteLoader(options.loadingTime); - } - }).catch(function () { - // 捕获错误并显示错误信息 - miniAdmin.error('菜单接口有误'); - }) - }, - - /** - * 初始化logo - * @param data - */ - renderLogo: function (data) { - // 生成包含logo图片和标题的HTML字符串 - var html = 'logo

' + data.title + '

'; - - // 将生成的HTML字符串插入到class为layuimini-logo的元素中 - $('.layuimini-logo').html(html); - }, - - /** - * 初始化缓存地址 - * @param clearUrl - */ - renderClear: function (clearUrl) { - // 将传入的URL设置为'.layuimini-clear'元素的data-href属性值 - $('.layuimini-clear').attr('data-href', clearUrl); - }, - - /** - * 切换菜单动画 - * @param anim - */ - renderAnim: function (anim) { - // 检查传入的动画参数是否存在 - if (anim) { - // 在ID为'layuimini-bg-color'的元素之后插入一段样式代码,用于定义页面动画效果 - $('#layuimini-bg-color').after(''); - } - }, - - /** - * 进入全屏 - */ - fullScreen: function () { - // 获取文档的根元素 - var el = document.documentElement; - // 获取不同浏览器的全屏请求方法 - var rfs = el.requestFullScreen || el.webkitRequestFullScreen; - - // 如果支持标准的全屏请求方法,则调用该方法 - if (typeof rfs != "undefined" && rfs) { - rfs.call(el); - } - // 如果支持ActiveXObject(主要用于IE),则通过发送F11键实现全屏 - else if (typeof window.ActiveXObject != "undefined") { - var wscript = new ActiveXObject("WScript.Shell"); - if (wscript != null) { - wscript.SendKeys("{F11}"); - } - } - // 针对IE的msRequestFullscreen方法 - else if (el.msRequestFullscreen) { - el.msRequestFullscreen(); - } - // 针对Opera的oRequestFullscreen方法 - else if (el.oRequestFullscreen) { - el.oRequestFullscreen(); - } - // 针对Webkit内核的webkitRequestFullscreen方法 - else if (el.webkitRequestFullscreen) { - el.webkitRequestFullscreen(); - } - // 针对Firefox的mozRequestFullScreen方法 - else if (el.mozRequestFullScreen) { - el.mozRequestFullScreen(); - } - // 如果以上方法都不支持,则提示用户浏览器不支持全屏调用 - else { - miniAdmin.error('浏览器不支持全屏调用!'); - } - }, - - /** - * 退出全屏 - */ - exitFullScreen: function () { - // 获取文档对象 - var el = document; - // 定义取消全屏的方法,兼容不同浏览器 - var cfs = el.cancelFullScreen || el.webkitCancelFullScreen || el.exitFullScreen; - // 如果存在取消全屏方法并且该方法可用 - if (typeof cfs != "undefined" && cfs) { - // 调用取消全屏方法 - cfs.call(el); - } else if (typeof window.ActiveXObject != "undefined") { - // 针对IE浏览器的处理方式 - var wscript = new ActiveXObject("WScript.Shell"); - if (wscript != null) { - // 发送F11键以退出全屏模式 - wscript.SendKeys("{F11}"); - } - } else if (el.msExitFullscreen) { - // 针对IE11及以下版本的处理方式 - el.msExitFullscreen(); - } else if (el.oRequestFullscreen) { - // 针对Opera浏览器的处理方式 - el.oCancelFullScreen(); - } else if (el.mozCancelFullScreen) { - // 针对Firefox浏览器的处理方式 - el.mozCancelFullScreen(); - } else if (el.webkitCancelFullScreen) { - // 针对Webkit内核的浏览器(如Chrome和Safari)的处理方式 - el.webkitCancelFullScreen(); - } else { - // 如果以上所有方法都不可用,提示用户浏览器不支持全屏调用 - miniAdmin.error('浏览器不支持全屏调用!'); - } - }, - - /** - * 初始化设备端 - */ - renderDevice: function () { - // 如果当前是移动设备 - if (miniAdmin.checkMobile()) { - // 设置工具栏图标的属性为展开状态 - $('.layuimini-tool i').attr('data-side-fold', 1); - // 更改工具栏图标的类名为“fa fa-outdent” - $('.layuimini-tool i').attr('class', 'fa fa-outdent'); - // 移除布局主体的最小化样式 - $('.layui-layout-body').removeClass('layuimini-mini'); - // 添加布局主体的全部显示样式 - $('.layui-layout-body').addClass('layuimini-all'); - } - }, - - - /** - * 初始化加载时间 - * @param loadingTime - */ - deleteLoader: function (loadingTime) { - // 设置一个定时器,在指定的时间后执行回调函数 - setTimeout(function () { - // 使用jQuery选择器找到类名为'layuimini-loader'的元素,并使其淡出 - $('.layuimini-loader').fadeOut(); - }, loadingTime * 1000) // 将传入的loadingTime参数转换为毫秒 - }, - - /** - * 成功 - * @param title - * @returns {*} - */ - success: function (title) { - // 调用layer.msg方法显示消息提示框 - // title: 要显示的消息内容 - // icon: 1 表示成功图标 - // shade: 使用当前对象的shade属性作为遮罩层 - // scrollbar: false 表示不显示滚动条 - // time: 2000 表示消息提示框显示时间为2秒 - // shadeClose: true 表示点击遮罩层可以关闭提示框 - return layer.msg(title, {icon: 1, shade: this.shade, scrollbar: false, time: 2000, shadeClose: true}); - }, - - /** - * 失败 - * @param title - * @returns {*} - */ - error: function (title) { - // 调用layer.msg方法显示错误消息 - // title: 要显示的消息内容 - // icon: 2 表示使用错误图标 - // shade: 使用当前对象的shade属性值 - // scrollbar: false 表示不显示滚动条 - // time: 3000 表示消息显示时间为3秒 - // shadeClose: true 表示点击遮罩层可以关闭消息框 - return layer.msg(title, {icon: 2, shade: this.shade, scrollbar: false, time: 3000, shadeClose: true}); - }, - - /** - * 判断是否为手机 - * @returns {boolean} - */ - checkMobile: function () { - // 获取用户代理字符串并转换为小写 - var ua = navigator.userAgent.toLocaleLowerCase(); - // 获取平台信息并转换为小写 - var pf = navigator.platform.toLocaleLowerCase(); - // 判断是否为Android设备 - var isAndroid = (/android/i).test(ua) || ((/iPhone|iPod|iPad/i).test(ua) && (/linux/i).test(pf)) - || (/ucweb.*linux/i.test(ua)); - // 判断是否为iOS设备,排除Android设备 - var isIOS = (/iPhone|iPod|iPad/i).test(ua) && !isAndroid; - // 判断是否为Windows Phone设备 - var isWinPhone = (/Windows Phone|ZuneWP7/i).test(ua); - // 获取文档的宽度 - var clientWidth = document.documentElement.clientWidth; - // 如果既不是Android、iOS也不是Windows Phone,并且宽度大于1024,则返回false - if (!isAndroid && !isIOS && !isWinPhone && clientWidth > 1024) { - return false; - } else { - // 否则返回true - return true; - } - }, - - /** - * 监听 - * @param options - */ - listen: function (options) { - // 如果 options 对象中没有 homeInfo 属性,则初始化为一个空对象 - options.homeInfo = options.homeInfo || {}; - } - - /** - * 清理 - */ - $('body').on('click', '[data-clear]', function () { - // 显示加载动画,设置2秒后自动关闭 - var loading = layer.load(0, {shade: false, time: 2 * 1000}); - - // 清空浏览器的sessionStorage - sessionStorage.clear(); - - // 获取清理缓存的URL - var clearUrl = $(this).attr('data-href'); - - // 如果URL存在且不为空 - if (clearUrl != undefined && clearUrl != '' && clearUrl != null) { - // 发送GET请求到服务器清理缓存 - $.getJSON(clearUrl, function (data, status) { - // 关闭加载动画 - layer.close(loading); - - // 根据服务器返回的状态码判断是否成功 - if (data.code != 1) { - // 清理失败,显示错误信息 - return miniAdmin.error(data.msg); - } else { - // 清理成功,显示成功信息 - return miniAdmin.success(data.msg); - } - }).fail(function () { - // 请求失败,关闭加载动画并显示错误信息 - layer.close(loading); - return miniAdmin.error('清理缓存接口有误'); - }); - } else { - // URL不存在或为空,直接关闭加载动画并显示成功信息 - layer.close(loading); - return miniAdmin.success('清除缓存成功'); - } - }); - /** - * 刷新 - */ - $('body').on('click', '[data-refresh]', function () { - // 当点击带有 data-refresh 属性的元素时,触发此事件处理函数 - miniPage.refresh(options); - // 调用 miniPage 对象的 refresh 方法,并传入 options 参数进行页面刷新 - miniAdmin.success('刷新成功'); - // 调用 miniAdmin 对象的 success 方法,显示“刷新成功”的提示信息 - }); - - /** - * 监听提示信息 - */ - $("body").on("mouseenter", ".layui-nav-tree .menu-li", function () { - // 如果当前是移动设备,则不执行后续代码 - if (miniAdmin.checkMobile()) { - return false; - } - // 获取当前元素的class属性值 - var classInfo = $(this).attr('class'), - // 获取当前元素的HTML内容 - tips = $(this).prop("innerHTML"), - // 获取工具栏的折叠状态 - isShow = $('.layuimini-tool i').attr('data-side-fold'); - // 如果工具栏未折叠且tips存在 - if (isShow == 0 && tips) { - // 构建提示信息HTML结构 - tips = ""; - // 显示提示信息 - window.openTips = layer.tips(tips, $(this), { - tips: [2, '#2f4056'], // 设置提示信息的位置和颜色 - time: 300000, // 设置提示信息的显示时间 - skin:"popup-tips", // 设置提示信息的样式 - // 成功回调函数 - success:function (el) { - // 调整提示信息的位置 - var left = $(el).position().left - 10; - $(el).css({ left:left }); - // 重新渲染元素 - element.render(); - } - }); - } - }); - $("body").on("mouseleave", ".popup-tips", function () { - // 当鼠标离开具有类名 'popup-tips' 的元素时触发事件 - if (miniAdmin.checkMobile()) { - // 如果当前设备是移动设备,则直接返回 false,不执行后续代码 - return false; - } - // 获取具有类名 'layuimini-tool i' 的元素的 'data-side-fold' 属性值 - var isShow = $('.layuimini-tool i').attr('data-side-fold'); - if (isShow == 0) { - // 如果 'data-side-fold' 属性值为 0,表示侧边栏未展开 - try { - // 尝试关闭弹出提示框 - layer.close(window.openTips); - } catch (e) { - // 如果关闭过程中发生异常,捕获异常并打印错误信息到控制台 - console.log(e.message); - } - } - }); - - /** - * 全屏 - */ - $('body').on('click', '[data-check-screen]', function () { - // 获取当前元素的 data-check-screen 属性值 - var check = $(this).attr('data-check-screen'); - - // 如果属性值为 'full',则进入全屏模式 - if (check == 'full') { - // 调用 miniAdmin 的 fullScreen 方法进入全屏模式 - miniAdmin.fullScreen(); - // 将属性值改为 'exit' - $(this).attr('data-check-screen', 'exit'); - // 修改按钮图标为压缩图标 - $(this).html(''); - } else { - // 否则退出全屏模式 - miniAdmin.exitFullScreen(); - // 将属性值改为 'full' - $(this).attr('data-check-screen', 'full'); - // 修改按钮图标为箭头图标 - $(this).html(''); - } - }); - - /** - * 点击遮罩层 - */ - $('body').on('click', '.layuimini-make', function () { - // 调用 miniAdmin 的 renderDevice 方法重新渲染设备 - miniAdmin.renderDevice(); - }); - -} -}; - -// 导出 miniAdmin 模块 -exports("miniAdmin", miniAdmin); -}); \ No newline at end of file diff --git a/cff/miniMenu.js b/cff/miniMenu.js deleted file mode 100644 index 49cb1dd..0000000 --- a/cff/miniMenu.js +++ /dev/null @@ -1,234 +0,0 @@ -layui.define(["element","laytpl" ,"jquery"], function (exports) { // 定义一个模块,依赖element、laytpl和jquery - var element = layui.element, // 获取layui的element模块 - $ = layui.$, // 获取layui的jQuery模块 - laytpl = layui.laytpl, // 获取layui的模板引擎模块 - layer = layui.layer; // 获取layui的弹出层模块 - - var miniMenu = { // 定义miniMenu对象 - - - render: function (options) { // 定义渲染函数 - options.menuList = options.menuList || []; // 如果未传入menuList,则默认为空数组 - options.multiModule = options.multiModule || false; // 如果未传入multiModule,则默认为false - options.menuChildOpen = options.menuChildOpen || false; // 如果未传入menuChildOpen,则默认为false - if (options.multiModule) { // 如果开启多模块 - miniMenu.renderMultiModule(options.menuList, options.menuChildOpen); // 调用多模块渲染函数 - } else { // 否则 - miniMenu.renderSingleModule(options.menuList, options.menuChildOpen); // 调用单模块渲染函数 - } - miniMenu.listen(); // 监听事件 - }, - - - renderSingleModule: function (menuList, menuChildOpen) { // 定义单模块渲染函数 - menuList = menuList || []; // 如果未传入menuList,则默认为空数组 - var leftMenuHtml = '', // 初始化左侧菜单HTML字符串 - childOpenClass = '', // 初始化子菜单打开类名 - leftMenuCheckDefault = 'layui-this'; // 设置默认选中样式类名 - var me = this ; // 保存当前上下文 - if (menuChildOpen) childOpenClass = ' layui-nav-itemed'; // 如果需要展开子菜单,添加对应的类名 - leftMenuHtml = this.renderLeftMenu(menuList,{ childOpenClass:childOpenClass }) ; // 渲染左侧菜单HTML - $('.layui-layout-body').addClass('layuimini-single-module'); // 给布局主体添加单模块标识类名 - $('.layuimini-header-menu').remove(); // 移除头部菜单 - $('.layuimini-menu-left').html(leftMenuHtml); // 将渲染好的左侧菜单HTML插入到左侧菜单容器中 - - element.init(); // 初始化layui元素 - }, - - compileMenu: function(menu,isSub){ - // 定义菜单HTML模板,使用laytpl语法进行条件渲染 - var menuHtml = '' ; - - // 如果isSub为true,则使用不同的HTML模板 - if(isSub){ - menuHtml = '' - } - - // 使用laytpl渲染菜单HTML模板并返回结果 - return laytpl(menuHtml).render(menu); - }, - - compileMenuContainer :function(menu,isSub){ - // 定义菜单容器的HTML模板,使用laytpl语法进行条件渲染 - var wrapperHtml = '' ; - - // 如果isSub为true,则使用不同的HTML模板 - if(isSub){ - wrapperHtml = '
{{d.children}}
' ; - } - - // 如果菜单没有子项,则返回空字符串 - if(!menu.children){ - return ""; - } - - // 使用laytpl渲染菜单容器的HTML模板并返回结果 - return laytpl(wrapperHtml).render(menu); - }, - - each:function(list,callback){ // 定义一个遍历函数,接收列表和回调函数作为参数 - var _list = []; // 初始化一个空数组用于存储处理后的结果 - for(var i = 0 ,length = list.length ; i/\n'; - // 根据href和menuList生成页面标题数组 - var pageTitleArray = miniPage.buildPageTitleArray(href, options.menuList); - // 如果页面标题数组不为空 - if (pageTitleArray.length > 0) { - // 遍历页面标题数组 - for (var key in pageTitleArray) { - key = parseInt(key); // 将key转换为整数类型 - // 如果不是最后一个元素,添加链接和分隔符 - if (key !== pageTitleArray.length - 1) { - pageTitleHtml += '' + pageTitleArray[key] + '/\n'; - } else { - // 如果是最后一个元素,只添加链接 - pageTitleHtml += '' + pageTitleArray[key] + '\n'; - } - } - } else { - // 如果页面标题数组为空,从sessionStorage中获取标题 - var title = sessionStorage.getItem('layuimini_page_title'); - // 如果标题为空或未定义,隐藏页面头部元素 - if (title === null || title === undefined || title === '') { - $('.layuimini-page-header').addClass('layui-hide'); - } else { - // 否则,添加标题到页面标题HTML中 - pageTitleHtml += '' + title + '\n'; - } - } - // 清空并更新页面头部的标题内容 - $('.layuimini-page-header .layuimini-page-title').empty().html(pageTitleHtml); - }, - - /** - * 初始化页面内容 - * @param options - * @param href - */ - renderPageContent: function (href, options) { - // 设置默认的 renderPageVersion 选项为 false,如果未提供该选项 - options.renderPageVersion = options.renderPageVersion || false; - - // 定义页面内容的容器选择器 - var container = '.layuimini-content-page'; - - // 如果需要渲染页面版本,则在 URL 中添加时间戳参数 - if (options.renderPageVersion) { - var v = new Date().getTime(); - href = href.indexOf("?") > -1 ? href + '&v=' + v : href + '?v=' + v; - } - - // 根据页面头部是否隐藏来调整内容容器的高度样式 - if ($(".layuimini-page-header").hasClass("layui-hide")) { - $(container).removeAttr("style"); - } else { - $(container).attr("style", "height: calc(100% - 36px)"); - } - - // 清空内容容器的 HTML 内容 - $(container).html(''); - - // 发起 AJAX 请求获取页面内容 - $.ajax({ - url: href, - type: 'get', - dataType: 'html', - success: function (data) { - // 将获取到的内容插入到内容容器中,并初始化元素 - $(container).html(data); - element.init(); - }, - error: function (xhr, textstatus, thrown) { - // 处理请求失败的情况,显示错误信息 - return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!'); - } - }); - }, - - /** - * 刷新页面内容 - * @param options - */ - refresh: function (options) { - // 获取当前URL的hash部分,并去掉开头的'#/' - var href = location.hash.replace(/^#\//, ''); - - // 如果href为空或未定义,则渲染主页内容 - if (href === null || href === undefined || href === '') { - miniPage.renderHome(options); - } else { - // 否则根据href渲染相应的页面内容 - miniPage.renderPageContent(href, options); - } - } - } - }, - - /** - * 构建页面标题数组 - * @param href - * @param menuList - */ - /** - * 构建页面标题数组 - * @param {string} href - 目标链接 - * @param {Array} menuList - 菜单列表 - * @returns {Array} - 包含页面标题的数组 - */ - buildPageTitleArray: function (href, menuList) { - // 初始化空数组,用于存储最终结果 - var array = [], - newArray = []; - // 遍历菜单列表中的每一项 - for (key in menuList) { - // 获取当前项 - var item = menuList[key]; - // 如果当前项的链接与目标链接匹配 - if (item.href === href) { - // 将当前项的标题添加到结果数组中 - array.push(item.title); - // 终止循环 - break; - } - // 如果当前项有子菜单 - if (item.child) { - // 递归调用自身,处理子菜单 - newArray = miniPage.buildPageTitleArray(href, item.child); - // 如果子菜单中有匹配项 - if (newArray.length > 0) { - // 将当前项的标题添加到子菜单结果数组的开头 - newArray.unshift(item.title); - // 合并当前项的标题和子菜单结果数组到最终结果数组中 - array = array.concat(newArray); - // 终止循环 - break; - } - } - } - // 返回最终结果数组 - return array; - }, - - /** - * 获取指定链接内容 - * @param href - * @returns {string} - */ - getHrefContent: function (href) { - // 初始化一个空字符串变量,用于存储获取的内容 - var content = ''; - // 获取当前时间的时间戳,用于防止缓存 - var v = new Date().getTime(); - // 发送AJAX请求以获取指定URL的内容 - $.ajax({ - // 根据URL是否包含查询参数来决定如何添加时间戳 - url: href.indexOf("?") > -1 ? href + '&v=' + v : href + '?v=' + v, - // 设置请求类型为GET - type: 'get', - // 期望的响应数据类型为HTML - dataType: 'html', - // 设置请求为同步,等待响应后再继续执行后续代码 - async: false, - // 请求成功时的回调函数 - success: function (data) { - // 将获取到的数据赋值给content变量 - content = data; - }, - // 请求失败时的回调函数 - error: function (xhr, textstatus, thrown) { - // 显示错误信息并返回提示消息 - return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!'); - } - }); - // 返回获取到的内容 - return content; - }, - /** - * 获取弹出层的宽高 - * @returns {jQuery[]} - */ - getOpenWidthHeight: function () { - // 获取页面内容区域的宽度 - var clienWidth = $(".layuimini-content-page").width(); - // 获取页面内容区域的高度 - var clientHeight = $(".layuimini-content-page").height(); - // 获取页面内容区域相对于文档的左偏移量 - var offsetLeft = $(".layuimini-content-page").offset().left; - // 获取页面内容区域相对于文档的上偏移量 - var offsetTop = $(".layuimini-content-page").offset().top; - // 返回包含宽度、高度、上偏移量和左偏移量的数组 - return [clienWidth, clientHeight, offsetTop, offsetLeft]; - }, - /** - * 单模块切换 - * @param tabId - */ - listenSwitchSingleModule: function (tabId) { - // 遍历所有具有layuimini-href属性的元素 - $("[layuimini-href]").each(function () { - // 如果元素的layuimini-href属性值等于传入的tabId - if ($(this).attr("layuimini-href") === tabId) { - // 定义一个函数用于自动展开菜单栏 - var addMenuClass = function ($element, type) { - if (type === 1) { - // 为当前元素添加layui-this类 - $element.addClass('layui-this'); - // 如果当前元素同时拥有layui-nav-item和layui-this类 - if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-this')) { - // 将所有菜单项的类名设置为layui-nav-item - $(".layuimini-header-menu li").attr('class', 'layui-nav-item'); - } else { - // 递归调用addMenuClass,处理父级元素 - addMenuClass($element.parent().parent(), 2); - } - } else { - // 为当前元素添加layui-nav-itemed类 - $element.addClass('layui-nav-itemed'); - // 如果当前元素同时拥有layui-nav-item和layui-nav-itemed类 - if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-nav-itemed')) { - // 将所有菜单项的类名设置为layui-nav-item - $(".layuimini-header-menu li").attr('class', 'layui-nav-item'); - } else { - // 递归调用addMenuClass,处理父级元素 - addMenuClass($element.parent().parent(), 2); - } - } - }; - // 调用addMenuClass函数,展开当前元素的菜单栏 - addMenuClass($(this).parent(), 1); - // 终止each循环 - return false; - } - }); - }, - - /** - * 多模块切换 - * @param tabId - */ - listenSwitchMultiModule: function (tabId) { - // 遍历所有具有 layuimini-href 属性的元素 - $("[layuimini-href]").each(function () { - // 如果元素的 layuimini-href 属性值等于传入的 tabId - if ($(this).attr("layuimini-href") === tabId) { - - // 定义一个函数,用于自动展开菜单栏 - var addMenuClass = function ($element, type) { - if (type === 1) { - // 为元素添加 'layui-this' 类 - $element.addClass('layui-this'); - // 如果元素同时具有 'layui-nav-item' 和 'layui-this' 类 - if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-this')) { - // 获取父元素的 id - var moduleId = $element.parent().attr('id'); - // 设置头部菜单项的类名为 'layui-nav-item' - $(".layuimini-header-menu li").attr('class', 'layui-nav-item'); - // 为对应的头部菜单项添加 'layui-this' 类 - $("#" + moduleId + "HeaderId").addClass("layui-this"); - // 隐藏左侧菜单树 - $(".layuimini-menu-left .layui-nav.layui-nav-tree").attr('class', 'layui-nav layui-nav-tree layui-hide'); - // 显示当前模块的菜单树并添加 'layui-this' 类 - $("#" + moduleId).attr('class', 'layui-nav layui-nav-tree layui-this'); - } else { - // 递归调用 addMenuClass 函数,处理父级元素 - addMenuClass($element.parent().parent(), 2); - } - } else { - // 为元素添加 'layui-nav-itemed' 类 - $element.addClass('layui-nav-itemed'); - // 如果元素同时具有 'layui-nav-item' 和 'layui-nav-itemed' 类 - if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-nav-itemed')) { - // 获取父元素的 id - var moduleId = $element.parent().attr('id'); - // 设置头部菜单项的类名为 'layui-nav-item' - $(".layuimini-header-menu li").attr('class', 'layui-nav-item'); - // 为对应的头部菜单项添加 'layui-this' 类 - $("#" + moduleId + "HeaderId").addClass("layui-this"); - // 隐藏左侧菜单树 - $(".layuimini-menu-left .layui-nav.layui-nav-tree").attr('class', 'layui-nav layui-nav-tree layui-hide'); - // 显示当前模块的菜单树并添加 'layui-this' 类 - $("#" + moduleId).attr('class', 'layui-nav layui-nav-tree layui-this'); - } else { - // 递归调用 addMenuClass 函数,处理父级元素 - addMenuClass($element.parent().parent(), 2); - } - } - }; - // 调用 addMenuClass 函数,处理当前元素的父级元素 - addMenuClass($(this).parent(), 1); - return false; // 终止 each 循环 - } - }); - }, - /** - * 修改hash地址定位 - * @param href - */ - hashChange: function (href) { - // 将传入的 href 参数拼接到当前 URL 的哈希部分,并更新浏览器地址栏 - window.location.hash = "/" + href; - }, - - /** - * 修改hash地址为主页 - */ - hashHome: function () { - // 将当前窗口的哈希值设置为根路径 "/" - window.location.hash = "/"; - }, - - /** - * 监听 - * @param options - */ - /** - * 监听函数,用于处理传入的选项参数。 - * @param {Object} options - 配置选项对象。 - */ - listen: function (options) { - // 方法体内容待补充 - /** - * 打开新窗口 - */ - $('body').on('click', '[layuimini-href]', function () { - // 显示加载动画,设置2秒后自动关闭 - var loading = layer.load(0, {shade: false, time: 2 * 1000}); - - // 获取当前点击元素的layuimini-href属性值和target属性值 - var href = $(this).attr('layuimini-href'), - target = $(this).attr('target'); - - // 如果href为空,则直接返回 - if(!href) return; - - // 保存当前点击的元素引用 - var me = this; - - // 查找左侧菜单中与当前点击元素href相同的元素 - var el = $("[layuimini-href='"+href+"']",".layuimini-menu-left"); - - // 关闭之前打开的提示框 - layer.close(window.openTips); - - // 如果找到匹配的元素 - if(el.length){ - // 移除所有layui-this类名 - $(el).closest(".layui-nav-tree").find(".layui-this").removeClass("layui-this"); - // 给父元素添加layui-this类名 - $(el).parent().addClass("layui-this"); - } - - // 如果target属性值为_blank,则在新窗口中打开链接 - if (target === '_blank') { - // 关闭加载动画 - layer.close(loading); - // 在新窗口中打开链接 - window.open(href, "_blank"); - return false; - } - - // 调用miniPage对象的hashChange方法,改变页面URL的哈希值 - miniPage.hashChange(href); - - // 设置左侧菜单的layuimini-page-add属性为yes - $('.layuimini-menu-left').attr('layuimini-page-add', 'yes'); - - // 关闭加载动画 - layer.close(loading); - }); - - /** - * 在子页面上打开新窗口 - */ - $('body').on('click', '[layuimini-content-href]', function () { - // 显示加载动画,设置2秒后自动关闭 - var loading = parent.layer.load(0, {shade: false, time: 2 * 1000}); - - // 获取点击元素的href、title和target属性值 - var href = $(this).attr('layuimini-content-href'), - title = $(this).attr('data-title'), - target = $(this).attr('target'); - - // 如果href为空,则直接返回 - if(!href) return; - - // 保存当前点击的元素引用 - var me = this; - - // 查找左侧菜单中匹配的href元素 - var el = $("[layuimini-href='"+href+"']",".layuimini-menu-left"); - - // 关闭之前打开的提示框 - layer.close(window.openTips); - - // 如果找到匹配的元素 - if(el.length){ - // 移除所有同级元素的'layui-this'类 - $(el).closest(".layui-nav-tree").find(".layui-this").removeClass("layui-this"); - // 给父元素添加'layui-this'类 - $(el).parent().addClass("layui-this"); - } - - // 如果target属性为'_blank',则在新窗口中打开链接 - if (target === '_blank') { - // 关闭加载动画 - parent.layer.close(loading); - // 在新窗口中打开链接 - window.open(href, "_blank"); - return false; - } - - // 将页面标题存储到sessionStorage中 - sessionStorage.setItem('layuimini_page_title', title); - - // 调用hashChange方法更新页面内容 - miniPage.hashChange(href); - - // 关闭加载动画 - parent.layer.close(loading); - }); - - /** - * 返回主页 - */ - $('body').on('click', '.layuimini-back-home', function () { - // 当点击事件触发时,调用 miniPage 对象的 hashHome 方法 - miniPage.hashHome(); - }); - - - }, - - - /** - * 监听hash变化 - * @returns {boolean} - */ - listenHash: function (options) { - // 初始化homeInfo选项,如果未定义则设置为空对象 - options.homeInfo = options.homeInfo || {}; - // 初始化multiModule选项,如果未定义则设置为false - options.multiModule = options.multiModule || false; - // 初始化listenSwichCallback选项,如果未定义则设置为空函数 - options.listenSwichCallback = options.listenSwichCallback || function () {}; - - // 监听hash变化事件 - window.onhashchange = function () { - // 获取当前hash值并去掉前缀'#/' - var href = location.hash.replace(/^#\//, ''); - - // 如果listenSwichCallback是函数,则调用它 - if (typeof options.listenSwichCallback === 'function') { - options.listenSwichCallback(); - } - - // 根据hash值判断要渲染的页面 - if (href === null || href === undefined || href === '') { - // 如果hash值为空,移除layui-this类并渲染首页 - $("[layuimini-href]").parent().removeClass('layui-this'); - miniPage.renderHome(options); - } else { - // 否则渲染指定页面 - miniPage.renderPage(href, options); - } - - // 检查菜单是否添加了新页面 - if ($('.layuimini-menu-left').attr('layuimini-page-add') === 'yes') { - // 如果是,则重置属性为'no' - $('.layuimini-menu-left').attr('layuimini-page-add', 'no'); - } else { - // 如果不是,重新定位菜单焦点 - $("[layuimini-href]").parent().removeClass('layui-this'); - if (options.multiModule) { - // 多模块情况下处理菜单切换 - miniPage.listenSwitchMultiModule(href); - } else { - // 单模块情况下处理菜单切换 - miniPage.listenSwitchSingleModule(href); - } - } - }; - }, \ No newline at end of file diff --git a/cff/miniTheme.js b/cff/miniTheme.js deleted file mode 100644 index e4ca747..0000000 --- a/cff/miniTheme.js +++ /dev/null @@ -1,576 +0,0 @@ -layui.define(["jquery", "layer"], function (exports) { - // 获取jQuery对象 - var $ = layui.$, - // 获取Layer对象 - layer = layui.layer; - - // 定义miniTheme对象 - var miniTheme = { - - /** - * 主题配置项 - * @param bgcolorId - * @returns {{headerLogo, menuLeftHover, headerRight, menuLeft, headerRightThis, menuLeftThis}|*|*[]} - */ - config: function (bgcolorId) { - // 定义一个名为bgColorConfig的数组,用于存储背景颜色配置 - var bgColorConfig = [ - { - headerRightBg: '#ffffff', //头部右侧背景色 - headerRightBgThis: '#e4e4e4', //头部右侧选中背景色, - headerRightColor: 'rgba(107, 107, 107, 0.7)', //头部右侧字体颜色, - headerRightChildColor: 'rgba(107, 107, 107, 0.7)', //头部右侧下拉字体颜色, - headerRightColorThis: '#565656', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(160, 160, 160, 0.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#1E9FFF', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#565656', //头部缩放按钮样式, - headerLogoBg: '#192027', //logo背景颜色, - headerLogoColor: 'rgb(191, 187, 187)', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#28333E', //左侧菜单背景, - leftMenuBgThis: '#1E9FFF', //左侧菜单选中背景, - leftMenuChildBg: '#0c0f13', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#1e9fff', //tab选项卡选中颜色, - }, - { - headerRightBg: '#23262e', //头部右侧背景色 - headerRightBgThis: '#0c0c0c', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#0c0c0c', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#23262e', //左侧菜单背景, - leftMenuBgThis: '#737373', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#23262e', //tab选项卡选中颜色, - }, - { - headerRightBg: '#ffa4d1', //头部右侧背景色 - headerRightBgThis: '#bf7b9d', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#ffa4d1', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#e694bd', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#1f1f1f', //左侧菜单背景, - leftMenuBgThis: '#737373', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#ffa4d1', //tab选项卡选中颜色, - }, - { - headerRightBg: '#1aa094', //头部右侧背景色 - headerRightBgThis: '#197971', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#0c0c0c', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#23262e', //左侧菜单背景, - leftMenuBgThis: '#1aa094', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#1aa094', //tab选项卡选中颜色, - }, - { - headerRightBg: '#1e9fff', //头部右侧背景色 - headerRightBgThis: '#0069b7', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#1e9fff', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#0c0c0c', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#1f1f1f', //左侧菜单背景, - leftMenuBgThis: '#1e9fff', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#1e9fff', //tab选项卡选中颜色, - }, - { - headerRightBg: '#ffb800', //头部右侧背景色 - headerRightBgThis: '#d09600', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#d09600', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#243346', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#2f4056', //左侧菜单背景, - leftMenuBgThis: '#8593a7', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#ffb800', //tab选项卡选中颜色, - }, - { - headerRightBg: '#e82121', //头部右侧背景色 - headerRightBgThis: '#ae1919', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#ae1919', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#0c0c0c', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#1f1f1f', //左侧菜单背景, - leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#e82121', //tab选项卡选中颜色, - }, - { - headerRightBg: '#963885', //头部右侧背景色 - headerRightBgThis: '#772c6a', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#772c6a', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#243346', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#2f4056', //左侧菜单背景, - leftMenuBgThis: '#586473', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#963885', //tab选项卡选中颜色, - }, - { - headerRightBg: '#2D8CF0', //头部右侧背景色 - headerRightBgThis: '#0069b7', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#0069b7', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#0069b7', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#1f1f1f', //左侧菜单背景, - leftMenuBgThis: '#2D8CF0', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#2d8cf0', //tab选项卡选中颜色, - }, - { - headerRightBg: '#ffb800', //头部右侧背景色 - headerRightBgThis: '#d09600', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#d09600', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#d09600', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#2f4056', //左侧菜单背景, - leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#ffb800', //tab选项卡选中颜色, - }, - { - headerRightBg: '#e82121', //头部右侧背景色 - headerRightBgThis: '#ae1919', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#ae1919', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#d91f1f', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#1f1f1f', //左侧菜单背景, - leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#e82121', //tab选项卡选中颜色, - }, - { - headerRightBg: '#963885', //头部右侧背景色 - headerRightBgThis: '#772c6a', //头部右侧选中背景色, - headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色, - headerRightChildColor: '#676767', //头部右侧下拉字体颜色, - headerRightColorThis: '#ffffff', //头部右侧鼠标选中, - headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色, - headerRightNavMoreBg: '#772c6a', //头部右侧更多下拉列表选中背景色, - headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色, - headerRightToolColor: '#bbe3df', //头部缩放按钮样式, - headerLogoBg: '#772c6a', //logo背景颜色, - headerLogoColor: '#ffffff', //logo字体颜色, - leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式, - leftMenuBg: '#2f4056', //左侧菜单背景, - leftMenuBgThis: '#626f7f', //左侧菜单选中背景, - leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景, - leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色, - leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色, - tabActiveColor: '#963885', //tab选项卡选中颜色, - } - ]; - // 检查bgcolorId是否未定义 - if (bgcolorId === undefined) { - // 如果bgcolorId未定义,返回整个背景颜色配置对象 - return bgColorConfig; - } else { - // 如果bgcolorId已定义,返回对应ID的背景颜色配置 - return bgColorConfig[bgcolorId]; - } - } - }, - - /** - * 初始化 - * @param options - */ - render: function (options) { - // 设置默认背景颜色选项,如果未定义则设为false - options.bgColorDefault = options.bgColorDefault || false; - // 设置监听选项,如果未定义则设为false - options.listen = options.listen || false; - // 从sessionStorage中获取背景颜色ID - var bgcolorId = sessionStorage.getItem('layuiminiBgcolorId'); - // 如果背景颜色ID不存在或为空字符串,则使用默认背景颜色ID - if (bgcolorId === null || bgcolorId === undefined || bgcolorId === '') { - bgcolorId = options.bgColorDefault; - } - // 构建主题CSS文件 - miniTheme.buildThemeCss(bgcolorId); - // 如果需要监听,则调用监听方法 - if (options.listen) miniTheme.listen(options); - }, - - /** - * 构建主题样式 - * @param bgcolorId - * @returns {boolean} - */ - buildThemeCss: function (bgcolorId) { - // 检查是否提供了背景颜色ID,如果没有则返回false - if (!bgcolorId) { - return false; - } - // 获取指定ID的背景颜色配置数据 - var bgcolorData = miniTheme.config(bgcolorId); - // 构建CSS样式字符串 - // 定义一个包含CSS样式的字符串,用于设置头部右侧背景色 - var styleHtml = '/*头部右侧背景色 headerRightBg */\n' + - '.layui-layout-admin .layui-header {\n' + - // 使用bgcolorData对象中的headerRightBg属性值设置背景颜色,并添加!important确保优先级 - ' background-color: ' + bgcolorData.headerRightBg + ' !important;\n' + - '}\n' + - '\n' + - '/*头部右侧选中背景色 headerRightBgThis */\n' + - // 选择器:匹配layui-layout-admin类下的layui-header内的layuimini-header-content的子元素ul中的layui-nav-item类和layui-this类,以及layuimini-tool内的i元素在悬停时 - '.layui-layout-admin .layui-header .layuimini-header-content > ul > .layui-nav-item.layui-this, .layuimini-tool i:hover {\n' + - // 设置背景颜色为bgcolorData对象中的headerRightBgThis属性值,并添加!important以覆盖其他样式 - ' background-color: ' + bgcolorData.headerRightBgThis + ' !important;\n' + - '}\n' + - '\n' + - '/*头部右侧字体颜色 headerRightColor */\n' + - // 选择器:.layui-layout-admin 下的 .layui-header 中的 .layui-nav 的 .layui-nav-item 内的 a 元素 - '.layui-layout-admin .layui-header .layui-nav .layui-nav-item a {\n' + - // 设置字体颜色为 bgcolorData 对象中的 headerRightColor 属性值 - ' color: ' + bgcolorData.headerRightColor + ';\n' + - '}\n' + - '\n' + - /**头部右侧下拉字体颜色 headerRightChildColor */ - '.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child a {\n' + - // 设置下拉菜单中链接的字体颜色,使用 !important 确保优先级最高 - ' color: ' + bgcolorData.headerRightChildColor + '!important;\n' + - '}\n' + - '\n' + - // 定义CSS样式,当鼠标悬停在头部右侧菜单项上时,改变其颜色 - '/*头部右侧鼠标选中 headerRightColorThis */\n' + - '.layui-header .layuimini-menu-header-pc.layui-nav .layui-nav-item a:hover, .layui-header .layuimini-header-menu.layuimini-pc-show.layui-nav .layui-this {\n' + - // 设置颜色为bgcolorData对象中的headerRightColorThis属性值,并使用!important确保优先级最高 - ' color: ' + bgcolorData.headerRightColorThis + ' !important;\n' + - '}\n' + - '\n' + - // 定义头部右侧更多下拉颜色样式 - '/*头部右侧更多下拉颜色 headerRightNavMore */\n' + - '.layui-header .layui-nav .layui-nav-more {\n' + - // 设置边框顶部颜色为指定的颜色,并使用!important确保优先级最高 - ' border-top-color: ' + bgcolorData.headerRightNavMore + ' !important;\n' + - '}\n' + - '\n' + - /**头部右侧更多下拉颜色 headerRightNavMore */ - '.layui-header .layui-nav .layui-nav-mored, .layui-header .layui-nav-itemed > a .layui-nav-more {\n' + - // 设置边框颜色,上和左为透明,右和下为指定的颜色 - ' border-color: transparent transparent ' + bgcolorData.headerRightNavMore + ' !important;\n' + - '}\n' + - '\n' + - /**头部右侧更多下拉配置色 headerRightNavMoreBg headerRightNavMoreColor */ - '.layui-header .layui-nav .layui-nav-child dd.layui-this a, .layui-header .layui-nav .layui-nav-child dd.layui-this,\n' + - '.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this a,\n' + - '.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this {\n' + - // 设置背景颜色为 headerRightNavMoreBg,并使用 !important 提升优先级 - ' background-color: ' + bgcolorData.headerRightNavMoreBg + ' !important;\n' + - // 设置文字颜色为 headerRightNavMoreColor,并使用 !important 提升优先级 - ' color:' + bgcolorData.headerRightNavMoreColor + ' !important;\n' + - '}\n' + - '\n' + - // 定义头部缩放按钮样式,使用传入的headerRightToolColor颜色值 - '/*头部缩放按钮样式 headerRightToolColor */\n' + - '.layui-layout-admin .layui-header .layuimini-tool i {\n' + - // 设置头部工具图标的颜色 - ' color: ' + bgcolorData.headerRightToolColor + ';\n' + - '}\n' + - '\n' + - // 生成包含logo背景颜色的CSS样式字符串 - '/*logo背景颜色 headerLogoBg */\n' + - '.layui-layout-admin .layuimini-logo {\n' + - // 设置logo的背景颜色,使用bgcolorData对象中的headerLogoBg属性值 - ' background-color: ' + bgcolorData.headerLogoBg + ' !important;\n' + - '}\n' + - '\n' + - // 定义一个CSS样式规则,用于设置layui-layout-admin类下的layuimini-logo中的h1元素的字体颜色 - '/*logo字体颜色 headerLogoColor */\n' + - '.layui-layout-admin .layuimini-logo h1 {\n' + - // 将h1元素的颜色设置为bgcolorData对象中的headerLogoColor属性值 - ' color: ' + bgcolorData.headerLogoColor + ';\n' + - '}\n' + - '\n' + - '/*左侧菜单更多下拉样式 leftMenuNavMore */\n' + - // 选择左侧菜单中的更多按钮,并设置其顶部边框颜色 - '.layuimini-menu-left .layui-nav .layui-nav-more,.layuimini-menu-left-zoom.layui-nav .layui-nav-more {\n' + - // 使用变量bgcolorData.leftMenuNavMore的值来设置顶部边框颜色 - ' border-top-color: ' + bgcolorData.leftMenuNavMore + ';\n' + - '}\n' + - '\n' + - /** 左侧菜单更多下拉样式 leftMenuNavMore */ - '.layuimini-menu-left .layui-nav .layui-nav-mored, .layuimini-menu-left .layui-nav-itemed > a .layui-nav-more, .layuimini-menu-left-zoom.layui-nav .layui-nav-mored, .layuimini-menu-left-zoom.layui-nav .layui-nav-itemed > a .layui-nav-more {\n' + - // 设置边框颜色,上和左为透明,右和下为指定背景色 - ' border-color: transparent transparent ' + bgcolorData.leftMenuNavMore + ' !important;\n' + - '}\n' + - '\n' + - '/*左侧菜单背景 leftMenuBg */\n' + - // 设置左侧菜单的背景颜色为黑色,并应用到指定的元素上 - '.layui-side.layui-bg-black, .layui-side.layui-bg-black > .layuimini-menu-left > ul, .layuimini-menu-left-zoom > ul {\n' + - // 使用变量bgcolorData中的leftMenuBg值作为背景颜色,并添加!important确保优先级 - ' background-color: ' + bgcolorData.leftMenuBg + ' !important;\n' + - '}\n' + - '\n' + - // 左侧菜单选中背景样式定义 - '/*左侧菜单选中背景 leftMenuBgThis */\n' + - // 设置左侧菜单中当前选中项的背景颜色 - '.layuimini-menu-left .layui-nav-tree .layui-this, .layuimini-menu-left .layui-nav-tree .layui-this > a, .layuimini-menu-left .layui-nav-tree .layui-this a, .layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a, .layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this,\n' + - // 设置左侧菜单缩放状态下当前选中项的背景颜色 - '.layuimini-menu-left-zoom.layui-nav-tree .layui-this, .layuimini-menu-left-zoom.layui-nav-tree .layui-this > a, .layuimini-menu-left-zoom.layui-nav-tree .layui-this a, .layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.lavueimini-tabactiveColoryt a, .layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this {\n' + - // 应用背景颜色,并使用!important确保优先级最高 - ' background-color: ' + bgcolorData.leftMenuBgThis + '!important\n' + - '}\n' + - '\n' + - '/*左侧菜单子菜单背景 leftMenuChildBg */\n' + - // 选择左侧菜单中已展开的父菜单项下的子菜单 - '.layuimini-menu-left .layui-nav-itemed > .layui-nav-child{\n' + - // 设置子菜单的背景颜色,并使用!important确保优先级最高 - ' background-color: ' + bgcolorData.leftMenuChildBg + ' !important;\n' + - '}\n' + - '\n' + - '/*左侧菜单字体颜色 leftMenuColor */\n' + - // 选择左侧菜单中的所有导航项链接,并设置其字体颜色为bgcolorData.leftMenuColor - '.layuimini-menu-left .layui-nav .layui-nav-item a, .layuimini-menu-left-zoom.layui-nav .layui-nav-item a {\n' + - // 使用!important确保颜色设置不会被其他CSS规则覆盖 - ' color: ' + bgcolorData.leftMenuColor + ' !important;\n' + - '}\n' + - '\n' + - // 定义左侧菜单选中字体颜色样式 - '/*左侧菜单选中字体颜色 leftMenuColorThis */\n' + - '.layuimini-menu-left .layui-nav .layui-nav-item a:hover, .layuimini-menu-left .layui-nav .layui-this a, .layuimini-menu-left-zoom.layui-nav .layui-nav-item a:hover, .layuimini-menu-left-zoom.layui-nav .layui-this a {\n' + - // 设置鼠标悬停或当前选中的菜单项字体颜色,并使用!important确保优先级最高 - ' color:' + bgcolorData.leftMenuColorThis + '!important;\n' + - '}\n' + - '\n' + - /** - * 设置tab选项卡选中颜色 - * @param {string} bgcolorData.tabActiveColor - tab选项卡选中时的背景颜色 - */ - '.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {\n' + - // 设置背景颜色为传入的tabActiveColor值 - ' background-color: ' + bgcolorData.tabActiveColor + ';\n' + - '}\n'; - //将生成的CSS样式插入到页面中 - // 将styleHtml的内容插入到ID为'layuimini-bg-color'的元素中 - $('#layuimini-bg-color').html(styleHtml); - /** - * 构建主题选择html - * @param options - * @returns {string} - */ - /** - * 构建背景颜色HTML字符串 - * @param {Object} options - 配置选项对象 - * @param {number} options.bgColorDefault - 默认背景颜色ID - * @returns {string} 生成的背景颜色HTML字符串 - */ - buildBgColorHtml: function (options) { - // 如果未定义默认背景颜色ID,则设置为0 - options.bgColorDefault = options.bgColorDefault || 0; - - // 从sessionStorage中获取当前背景颜色ID - var bgcolorId = parseInt(sessionStorage.getItem('layuiminiBgcolorId')); - - // 如果获取到的背景颜色ID不是数字,则使用默认背景颜色ID - if (isNaN(bgcolorId)) bgcolorId = options.bgColorDefault; - - // 获取背景颜色配置 - var bgColorConfig = miniTheme.config(); - - // 初始化HTML字符串 - var html = ''; - - // 遍历背景颜色配置 - $.each(bgColorConfig, function (key, val) { - // 如果当前背景颜色ID与配置中的ID相同,添加选中样式 - if (key === bgcolorId) { - html += '
  • \n'; - } else { - html += '
  • \n'; - } - - // 构建背景颜色HTML片段 - // 开始构建HTML字符串,添加一个链接元素,并设置其属性和样式 - html += '\n' + - // 添加第一个div元素,包含两个span子元素,用于显示头部背景颜色 - '
    \n' + - // 添加第二个div元素,包含两个span子元素,用于显示左侧菜单背景颜色和右侧白色背景 - '
    \n' + - // 关闭链接元素 - '
    \n' + - // 关闭列表项元素 - '
  • '; - }); - - // 返回生成的HTML字符串 - return html; - }, - - /** - * 监听 - * @param options - */ - listen: function (options) { - // 为body元素绑定点击事件,当点击带有data-bgcolor属性的元素时触发 - $('body').on('click', '[data-bgcolor]', function () { - // 显示加载动画,设置加载时间为2秒 - var loading = layer.load(0, {shade: false, time: 2 * 1000}); - // 获取当前文档高度减去60像素的值 - var clientHeight = (document.documentElement.clientHeight) - 60; - // 调用miniTheme对象的buildBgColorHtml方法生成背景颜色HTML代码 - var bgColorHtml = miniTheme.buildBgColorHtml(options); - // 构建配色方案的HTML结构 - // 定义一个包含HTML结构的字符串变量html - var html = '
    \n' + - // 添加一个包含配色方案标题的div元素 - '
    \n' + - // 在标题div中添加一个span元素,显示文本“配色方案” - '配色方案\n' + - '
    \n' + - // 添加一个包含配色内容的div元素 - '
    \n' + - // 在内容div中添加一个ul元素,用于存放背景颜色选项 - '
      \n' + bgColorHtml + '
    \n' + - '
    \n' + - '
    ' + - ''; - // 打开一个layer弹出层,显示配色方案选择器 - layer.open({ - type: 1, // 弹出层类型为页面层 - title: false, // 不显示标题 - closeBtn: 0, // 不显示关闭按钮 - shade: 0.2, // 遮罩透明度 - anim: 2, // 弹出动画效果 - shadeClose: true, // 点击遮罩区域是否允许关闭 - id: 'layuiminiBgColor', // 弹出层ID - area: ['340px', clientHeight + 'px'], // 弹出层宽高 - offset: 'rb', // 弹出层位置,右下角 - content: html, // 弹出层内容 - success: function (index, layero) { - // 弹出层成功打开后的回调函数 - }, - end: function () { - // 弹出层关闭后的回调函数,移除选中的背景颜色样式 - $('.layuimini-select-bgcolor').removeClass('layui-this'); - } - }); - // 关闭加载动画 - layer.close(loading); - }); - } - $('body').on('click', '[data-select-bgcolor]', function () { - // 获取点击元素的 data-select-bgcolor 属性值,作为背景颜色ID - var bgcolorId = $(this).attr('data-select-bgcolor'); - - // 移除当前选中的背景颜色样式类 - $('.layuimini-color .color-content ul .layui-this').attr('class', ''); - - // 为点击的元素添加选中的样式类 - $(this).attr('class', 'layui-this'); - - // 将背景颜色ID存储到 sessionStorage 中,以便后续使用 - sessionStorage.setItem('layuiminiBgcolorId', bgcolorId); - - // 调用 miniTheme.render 方法,更新主题背景颜色 - miniTheme.render({ - // 设置默认背景颜色为选中的背景颜色ID - bgColorDefault: bgcolorId, - // 不监听变化 - listen: false, - }); - }); - } - }; - - // 导出名为 "miniTheme" 的模块,供其他文件使用 - exports("miniTheme", miniTheme); -}) -; \ No newline at end of file diff --git a/cff/miniTongji.js b/cff/miniTongji.js deleted file mode 100644 index fc1b581..0000000 --- a/cff/miniTongji.js +++ /dev/null @@ -1,47 +0,0 @@ -layui.define(["jquery"], function (exports) { - // 引入jQuery库,并赋值给变量$ - var $ = layui.$; - - // 定义一个名为miniTongji的对象 - var miniTongji = { - - /** - * 初始化 - * @param options - */ - render: function (options) { - // 设置 options.specific 的默认值为 false - options.specific = options.specific || false; - // 设置 options.domains 的默认值为空数组 - options.domains = options.domains || []; - // 获取当前窗口的主机名 - var domain = window.location.hostname; - // 如果 options.specific 为 false,或者 options.specific 为 true 且域名在 options.domains 中 - if (options.specific === false || (options.specific === true && options.domains.indexOf(domain) >=0)) { - // 调用 miniTongji 对象的 listen 方法 - miniTongji.listen(); - } - }, - - /** - * 监听统计代码 - */ - listen: function () { - // 定义一个变量_hmt,如果_hmt未定义则初始化为空数组 - var _hmt = _hmt || []; - (function () { - // 创建一个新的script元素 - var hm = document.createElement("script"); - // 设置script元素的src属性为百度统计的脚本URL - hm.src = "https://hm.baidu.com/hm.js?d97abf6d61c21d773f97835defbdef4e"; - // 获取文档中第一个script标签 - var s = document.getElementsByTagName("script")[0]; - // 将新创建的script元素插入到第一个script标签之前 - s.parentNode.insertBefore(hm, s); - })(); - } - }; - - // 导出名为 "miniTongji" 的函数,供其他模块使用 - exports("miniTongji", miniTongji); -}); \ No newline at end of file diff --git a/cff/treetable.js b/cff/treetable.js deleted file mode 100644 index adcfb5f..0000000 --- a/cff/treetable.js +++ /dev/null @@ -1,308 +0,0 @@ -layui.define(['layer', 'table'], function (exports) { - // 获取jQuery对象 - var $ = layui.jquery; - // 获取layer模块 - var layer = layui.layer; - // 获取table模块 - var table = layui.table; - - var treetable = { - // 渲染树形表格 - render: function (param) { - // 检查参数是否合法 - if (!treetable.checkParam(param)) { - return; // 如果参数不合法,直接返回 - } - // 获取数据 - if (param.data) { - // 如果参数中包含数据,则直接初始化树形表格 - treetable.init(param, param.data); - } else { - // 如果参数中没有数据,则通过AJAX请求获取数据 - $.getJSON(param.url, param.where, function (res) { - // 使用获取到的数据初始化树形表格 - treetable.init(param, res.data); - }); - } - }, - // 渲染表格 - init: function (param, data) { - // 初始化一个空数组,用于存储处理后的数据 - var mData = []; - // 获取回调函数done - var doneCallback = param.done; - // 将传入的数据赋值给tNodes变量 - var tNodes = data; - // 遍历tNodes数组中的每一个元素 - for (var i = 0; i < tNodes.length; i++) { - // 当前遍历到的元素 - var tt = tNodes[i]; - // 如果当前元素没有id字段 - if (!tt.id) { - // 如果参数中没有treeIdName字段 - if (!param.treeIdName) { - // 弹出提示信息,告知treeIdName不能为空 - layer.msg('参数treeIdName不能为空', {icon: 5}); - // 终止函数执行 - return; - } - // 使用treeIdName对应的值作为id - tt.id = tt[param.treeIdName]; - } - // 检查tt对象是否具有pid属性 - if (!tt.pid) { - // 如果param对象没有treePidName属性,则提示错误信息并返回 - if (!param.treePidName) { - layer.msg('参数treePidName不能为空', {icon: 5}); - return; - } - // 将tt对象的pid属性设置为tt对象中对应treePidName属性的值 - tt.pid = tt[param.treePidName]; - } - } - - // 对数据进行排序 - var sort = function (s_pid, data) { - // 遍历数据数组 - for (var i = 0; i < data.length; i++) { - // 如果当前元素的父ID等于目标父ID - if (data[i].pid == s_pid) { - // 获取mData数组的长度 - var len = mData.length; - // 如果mData数组不为空且最后一个元素的ID等于目标父ID - if (len > 0 && mData[len - 1].id == s_pid) { - // 将最后一个元素的isParent属性设置为true - mData[len - 1].isParent = true; - } - // 将当前元素添加到mData数组中 - mData.push(data[i]); - // 递归调用sort函数,处理当前元素的子元素 - sort(data[i].id, data); - } - } - }; - } - }; - // 调用sort函数,对树形结构进行排序 - // 参数param.treeSpid表示树的根节点ID - // tNodes是包含所有节点信息的数组 - sort(param.treeSpid, tNodes); - - // 重写参数 - // 将param对象的url属性设置为undefined - param.url = undefined; - - // 将param对象的data属性设置为mData - param.data = mData; - - // 设置param对象的page属性,包含count和limit两个子属性 - param.page = { - // count属性表示数据的总数量,等于data数组的长度 - count: param.data.length, - // limit属性表示每页显示的数据量,等于data数组的长度 - limit: param.data.length - }; - param.cols[0][param.treeColIndex].templet = function (d) { - // 获取当前节点的ID - var mId = d.id; - // 获取当前节点的父节点ID - var mPid = d.pid; - // 判断当前节点是否为目录(是否有子节点) - var isDir = d.isParent; - // 计算当前节点前面需要填充的空白数量 - var emptyNum = treetable.getEmptyNum(mPid, mData); - // 初始化图标HTML字符串 - var iconHtml = ''; - // 根据空白数量生成相应数量的空白图标 - for (var i = 0; i < emptyNum; i++) { - iconHtml += ''; - } - if (isDir) { - // 如果是目录,添加两个图标:一个三角形和一个图层图标 - iconHtml += ' '; - } else { - // 如果是文件,添加一个文件图标 - iconHtml += ''; - } - // 添加两个空格作为间隔 - iconHtml += '  '; - // 根据是否是目录设置类型为'dir'或'file' - var ttype = isDir ? 'dir' : 'file'; - // 创建包含图标和名称的HTML字符串 - var vg = ''; - // 返回完整的HTML字符串 - return vg + iconHtml + d[param.cols[0][param.treeColIndex].field] + '' - - param.done = function (res, curr, count) { - // 在当前元素之后插入一个带有'class'为'treeTable'的元素 - $(param.elem).next().addClass('treeTable'); - - // 隐藏'treeTable'中的分页控件 - $('.treeTable .layui-table-page').css('display', 'none'); - - // 设置'treeTable'元素的'treeLinkage'属性 - $(param.elem).next().attr('treeLinkage', param.treeLinkage); - - // 注释掉的代码:绑定点击事件,用于切换行显示状态 - /*$('.treeTable .treeTable-icon').click(function () { - treetable.toggleRows($(this), param.treeLinkage); - });*/ - - // 如果设置了默认关闭树形结构,则折叠所有节点 - if (param.treeDefaultClose) { - treetable.foldAll(param.elem); - } - - // 如果存在回调函数,则执行回调函数 - if (doneCallback) { - doneCallback(res, curr, count); - } - }; - - // 渲染表格 - table.render(param); - }, - // 计算缩进的数量 - getEmptyNum: function (pid, data) { - // 初始化缩进数量为0 - var num = 0; - // 如果pid不存在,直接返回缩进数量0 - if (!pid) { - return num; - } - var tPid; - // 遍历数据数组 - for (var i = 0; i < data.length; i++) { - // 如果当前元素的id与pid匹配 - if (pid == data[i].id) { - // 增加缩进数量 - num += 1; - // 更新tPid为当前元素的父id - tPid = data[i].pid; - // 跳出循环 - break; - } - } - return num + treetable.getEmptyNum(tPid, data); - }, - // 展开/折叠行 - toggleRows: function ($dom, linkage) { - // 获取当前行的树类型 - var type = $dom.attr('lay-ttype'); - // 如果当前行是文件类型,则直接返回 - if ('file' == type) { - return; - } - // 获取当前行的ID - var mId = $dom.attr('lay-tid'); - // 判断当前行是否已经展开 - var isOpen = $dom.hasClass('open'); - // 如果已经展开,则移除展开类,否则添加展开类 - if (isOpen) { - $dom.removeClass('open'); - } else { - $dom.addClass('open'); - } - // 遍历当前行所在的tbody中的所有行 - $dom.closest('tbody').find('tr').each(function () { - // 获取当前行的图标元素 - var $ti = $(this).find('.treeTable-icon'); - // 获取当前行的父ID和类型 - var pid = $ti.attr('lay-tpid'); - var ttype = $ti.attr('lay-ttype'); - // 判断当前行的图标是否已经展开 - var tOpen = $ti.hasClass('open'); - // 如果当前行的父ID与目标ID相同 - if (mId == pid) { - // 如果目标行已经展开,则隐藏当前行 - if (isOpen) { - $(this).hide(); - // 如果当前行是目录且已经展开,则触发点击事件 - if ('dir' == ttype && tOpen == isOpen) { - $ti.trigger('click'); - } - } else { - // 如果目标行未展开,则显示当前行 - $(this).show(); - // 如果需要联动展开且当前行是目录且已经展开,则触发点击事件 - if (linkage && 'dir' == ttype && tOpen == isOpen) { - $ti.trigger('click'); - } - } - } - }); - }, - // 检查参数 - checkParam: function (param) { - // 检查参数param的treeSpid属性是否为空或未定义,如果是则弹出提示信息并返回false - if (!param.treeSpid && param.treeSpid != 0) { - layer.msg('参数treeSpid不能为空', {icon: 5}); - return false; - } - - // 检查参数param的treeColIndex属性是否为空或未定义,如果是则弹出提示信息并返回false - if (!param.treeColIndex && param.treeColIndex != 0) { - layer.msg('参数treeColIndex不能为空', {icon: 5}); - return false; - } - - // 如果所有检查都通过,则返回true - return true; - } - }, - // 展开所有 - expandAll: function (dom) { - // 获取传入的DOM元素,并找到其下一个具有'.treeTable'类的元素 - $(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () { - // 在当前行中找到具有'.treeTable-icon'类的元素 - var $ti = $(this).find('.treeTable-icon'); - // 获取该元素的'lay-ttype'属性值 - var ttype = $ti.attr('lay-ttype'); - // 检查该元素是否具有'open'类 - var tOpen = $ti.hasClass('open'); - // 如果'lay-ttype'属性值为'dir'且没有'open'类,则触发点击事件 - if ('dir' == ttype && !tOpen) { - $ti.trigger('click'); - } - }); - }, - // 折叠所有 - foldAll: function (dom) { - // 获取传入的DOM元素,并找到其下一个具有'.treeTable'类的元素 - $(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () { - // 在当前行中找到具有'.treeTable-icon'类的元素 - var $ti = $(this).find('.treeTable-icon'); - // 获取该元素的'lay-ttype'属性值 - var ttype = $ti.attr('lay-ttype'); - // 检查该元素是否具有'open'类 - var tOpen = $ti.hasClass('open'); - // 如果'lay-ttype'属性值为'dir'且该元素具有'open'类 - if ('dir' == ttype && tOpen) { - // 触发该元素的点击事件 - $ti.trigger('click'); - } - }); - } - }; - - // 加载并链接外部CSS文件,用于树形表格的样式 - layui.link(layui.cache.base + 'treetable-lay/treetable.css'); - - // 给图标列绑定事件 - $('body').on('click', '.treeTable .treeTable-icon', function () { - // 获取当前点击的图标所在的树表元素的 treeLinkage 属性值 - var treeLinkage = $(this).parents('.treeTable').attr('treeLinkage'); - - // 如果 treeLinkage 属性值为 'true',则调用 treetable.toggleRows 方法并传入 true 参数 - if ('true' == treeLinkage) { - treetable.toggleRows($(this), true); - } else { - // 否则调用 treetable.toggleRows 方法并传入 false 参数 - treetable.toggleRows($(this), false); - } - }); - }); - - // 导出名为 'treetable' 的模块,并将其赋值为 treetable 函数或对象 - exports('treetable', treetable); -}); diff --git a/cff/ztree.js b/cff/ztree.js deleted file mode 100644 index 59d797e..0000000 --- a/cff/ztree.js +++ /dev/null @@ -1,6148 +0,0 @@ -layui.define(['jquery'],function(exports){ - // 获取layui的jQuery模块 -} - let jQuery = layui.jquery; - - (function ($) { - // 定义设置对象、根节点对象和缓存对象 - var settings = {}, roots = {}, caches = {}, - // 核心默认常量 - _consts = { - className: { - BUTTON: "button", // 按钮类名 - LEVEL: "level", // 层级类名 - ICO_LOADING: "ico_loading", // 加载图标类名 - SWITCH: "switch", // 开关类名 - NAME: 'node_name' // 节点名称类名 - }, - event: { - // 节点创建事件 - NODECREATED: "ztree_nodeCreated", - // 点击事件 - CLICK: "ztree_click", - // 展开事件 - EXPAND: "ztree_expand", - // 折叠事件 - COLLAPSE: "ztree_collapse", - // 异步加载成功事件 - ASYNC_SUCCESS: "ztree_async_success", - // 异步加载错误事件 - ASYNC_ERROR: "ztree_async_error", - // 移除事件 - REMOVE: "ztree_remove", - // 选中事件 - SELECTED: "ztree_selected", - // 取消选中事件 - UNSELECTED: "ztree_unselected" - }, - id: { - // 定义一个对象,用于存储不同元素的ID前缀 - A: "_a", // 为元素A设置ID前缀为"_a" - ICON: "_ico", // 为ICON元素设置ID前缀为"_ico" - SPAN: "_span", // 为SPAN元素设置ID前缀为"_span" - SWITCH: "_switch", // 为SWITCH元素设置ID前缀为"_switch" - UL: "_ul" // 为UL元素设置ID前缀为"_ul" - }, - line: { - // 定义一个对象,用于存储不同线条类型的名称 - ROOT: "root", // 根线条类型 - ROOTS: "roots", // 多根线条类型 - CENTER: "center", // 中心线条类型 - BOTTOM: "bottom", // 底部线条类型 - NOLINE: "noline", // 无线条类型 - LINE: "line" // 普通线条类型 - }, - folder: { - // 定义文件夹状态为打开 - OPEN: "open", - // 定义文件夹状态为关闭 - CLOSE: "close", - // 定义文件夹类型为文档 - DOCU: "docu" - }, - node: { - // 当前选中的节点 - CURSELECTED: "curSelectedNode" - } - }, - //default setting of core - _setting = { - // 树的ID,用于标识树的唯一性 - treeId: "", - // 树的对象实例,初始化为null - treeObj: null, - // 视图设置对象 - view: { - // 自定义DOM节点添加函数,默认为null - addDiyDom: null, - // 是否自动取消选中状态,默认为true - autoCancelSelected: true, - // 双击展开节点,默认为true - dblClickExpand: true, - // 展开速度,可选值为"fast"或"slow" - expandSpeed: "fast", - // 字体样式设置,默认为空对象 - fontCss: {}, - // 节点类名设置,默认为空对象 - nodeClasses: {}, - // 节点名称是否作为HTML解析,默认为false - nameIsHTML: false, - // 是否允许多选,默认为true - selectedMulti: true, - // 是否显示图标,默认为true - showIcon: true, - // 是否显示连接线,默认为true - showLine: true, - // 是否显示标题,默认为true - showTitle: true, - // 文本是否可选择,默认为false - txtSelectedEnable: false - }, - data: { - // 定义树形结构数据的键名 - key: { - // 表示节点是否有子节点的键名 - isParent: "isParent", - // 表示子节点集合的键名 - children: "children", - // 表示节点名称的键名 - name: "name", - // 表示节点标题的键名,初始为空字符串 - title: "", - // 表示节点URL的键名 - url: "url", - // 表示节点图标的键名 - icon: "icon" - }, - // 定义渲染时使用的键名 - render: { - // 渲染时使用的名称键名,初始为null - name: null, - // 渲染时使用的标题键名,初始为null - title: null, - }, - simpleData: { - // 启用或禁用简单数据模式 - enable: false, - // 节点的唯一标识键名 - idKey: "id", - // 父节点的标识键名 - pIdKey: "pId", - // 根节点的父节点标识,默认为null表示没有父节点 - rootPId: null - }, - keep: { - // 是否保留父节点信息 - parent: false, - // 是否保留叶子节点信息 - leaf: false - } - }, - async: { - // 是否启用异步请求,默认为false - enable: false, - // 设置请求的内容类型,默认为"application/x-www-form-urlencoded" - contentType: "application/x-www-form-urlencoded", - // 设置请求的类型,默认为"post" - type: "post", - // 设置响应的数据类型,默认为"text" - dataType: "text", - // 设置请求的头部信息,默认为空对象 - headers: {}, - // 设置XHR对象的额外字段,默认为空对象 - xhrFields: {}, - // 设置请求的URL地址,默认为空字符串 - url: "", - // 自动添加到请求参数中的键值对数组,默认为空数组 - autoParam: [], - // 其他手动添加的请求参数键值对数组,默认为空数组 - otherParam: [], - // 数据过滤器函数,用于处理响应数据,默认为null - dataFilter: null - }, - callback: { - // 在异步操作之前执行的回调函数,默认为null - beforeAsync: null, - // 在节点被点击之前执行的回调函数,默认为null - beforeClick: null, - // 在节点被双击之前执行的回调函数,默认为null - beforeDblClick: null, - // 在节点被右键点击之前执行的回调函数,默认为null - beforeRightClick: null, - // 在鼠标按下节点之前执行的回调函数,默认为null - beforeMouseDown: null, - // 在鼠标释放节点之前执行的回调函数,默认为null - beforeMouseUp: null, - // 在节点展开之前执行的回调函数,默认为null - beforeExpand: null, - // 在节点折叠之前执行的回调函数,默认为null - beforeCollapse: null, - // 在节点移除之前执行的回调函数,默认为null - beforeRemove: null, - - // 异步操作失败时执行的回调函数,默认为null - onAsyncError: null, - // 异步操作成功时执行的回调函数,默认为null - onAsyncSuccess: null, - // 节点创建后执行的回调函数,默认为null - onNodeCreated: null, - // 节点被点击时执行的回调函数,默认为null - onClick: null, - // 节点被双击时执行的回调函数,默认为null - onDblClick: null, - // 节点被右键点击时执行的回调函数,默认为null - onRightClick: null, - // 鼠标按下节点时执行的回调函数,默认为null - onMouseDown: null, - // 鼠标释放节点时执行的回调函数,默认为null - onMouseUp: null, - // 节点展开时执行的回调函数,默认为null - onExpand: null, - // 节点折叠时执行的回调函数,默认为null - onCollapse: null, - // 节点移除时执行的回调函数,默认为null - onRemove: null - } - }, - //default root of core - //zTree use root to save full data - /** - * 初始化根节点 - * @param {Object} setting - 配置对象 - */ - _initRoot = function (setting) { - // 获取根节点,如果不存在则创建一个新的空对象 - var r = data.getRoot(setting); - if (!r) { - r = {}; - // 将新创建的根节点设置到数据中 - data.setRoot(setting, r); - } - // 初始化根节点的子节点为空数组 - data.nodeChildren(setting, r, []); - // 初始化根节点的扩展触发标志为false - r.expandTriggerFlag = false; - // 初始化当前选中列表为空数组 - r.curSelectedList = []; - // 初始化无选择状态为true - r.noSelection = true; - // 初始化已创建节点列表为空数组 - r.createdNodes = []; - // 初始化zId为0 - r.zId = 0; - // 初始化版本号为当前时间的时间戳 - r._ver = (new Date()).getTime(); - }, - //default cache of core - _initCache = function (setting) { - // 获取缓存对象,如果不存在则初始化一个新的空对象 - var c = data.getCache(setting); - if (!c) { - // 如果缓存对象不存在,创建一个新的空对象 - c = {}; - // 将新的空对象设置到缓存中 - data.setCache(setting, c); - } - // 初始化缓存对象的nodes属性为一个空数组 - c.nodes = []; - // 初始化缓存对象的doms属性为一个空数组 - c.doms = []; - }, - //default bindEvent of core - _bindEvent = function (setting) { - // 获取树对象和事件常量 - var o = setting.treeObj, - c = consts.event; - - // 绑定节点创建事件 - o.bind(c.NODECREATED, function (event, treeId, node) { - tools.apply(setting.callback.onNodeCreated, [event, treeId, node]); - }); - - // 绑定点击事件 - o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) { - tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]); - }); - - // 绑定展开事件 - o.bind(c.EXPAND, function (event, treeId, node) { - tools.apply(setting.callback.onExpand, [event, treeId, node]); - }); - - // 绑定折叠事件 - o.bind(c.COLLAPSE, function (event, treeId, node) { - tools.apply(setting.callback.onCollapse, [event, treeId, node]); - }); - - // 绑定异步加载成功事件 - o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) { - tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]); - }); - - // 绑定异步加载错误事件 - o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) { - tools.apply(setting.callback.onAsyncError, [event, treeId, node, XMLHttpRequest, textStatus, errorThrown]); - }); - - // 绑定移除事件 - o.bind(c.REMOVE, function (event, treeId, treeNode) { - tools.apply(setting.callback.onRemove, [event, treeId, treeNode]); - }); - - // 绑定选中事件 - o.bind(c.SELECTED, function (event, treeId, node) { - tools.apply(setting.callback.onSelected, [treeId, node]); - }); - - // 绑定取消选中事件 - o.bind(c.UNSELECTED, function (event, treeId, node) { - tools.apply(setting.callback.onUnSelected, [treeId, node]); - }); - }, - _unbindEvent = function (setting) { - // 获取树对象 - var o = setting.treeObj, - // 获取事件常量 - c = consts.event; - // 解绑节点创建事件 - o.unbind(c.NODECREATED) - // 解绑点击事件 - .unbind(c.CLICK) - // 解绑展开事件 - .unbind(c.EXPAND) - // 解绑折叠事件 - .unbind(c.COLLAPSE) - // 解绑异步成功事件 - .unbind(c.ASYNC_SUCCESS) - // 解绑异步错误事件 - .unbind(c.ASYNC_ERROR) - // 解绑移除事件 - .unbind(c.REMOVE) - // 解绑选中事件 - .unbind(c.SELECTED) - // 解绑取消选中事件 - .unbind(c.UNSELECTED); - }, - //default event proxy of core - _eventProxy = function (event) { - // 获取事件目标元素 - var target = event.target, - // 获取树的设置信息 - // 获取指定树的设置信息 - setting = data.getSetting(event.data.treeId), - // 初始化节点ID为空字符串 - tId = "", - // 初始化节点对象为null - node = null, - // 初始化节点事件类型为空字符串 - nodeEventType = "", - // 初始化树事件类型为空字符串 - treeEventType = "", - // 初始化节点事件回调函数为null - nodeEventCallback = null, - // 初始化树事件回调函数为null - treeEventCallback = null, - // 初始化临时变量为null - tmp = null; - - // 根据事件类型判断是哪种树事件 - if (tools.eqs(event.type, "mousedown")) { - // 如果事件类型是鼠标按下,则设置树事件类型为"mousedown" - treeEventType = "mousedown"; - } else if (tools.eqs(event.type, "mouseup")) { - // 如果事件类型是鼠标抬起,则设置树事件类型为"mouseup" - treeEventType = "mouseup"; - } else if (tools.eqs(event.type, "contextmenu")) { - // 如果事件类型是右键菜单,则设置树事件类型为"contextmenu" - treeEventType = "contextmenu"; - } else if (tools.eqs(event.type, "click")) { - // 如果点击的是节点开关,则设置节点事件类型为switchNode - if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.SWITCH) !== null) { - // 获取主DOM元素的ID并赋值给tId - tId = tools.getNodeMainDom(target).id; - // 设置节点事件类型为"switchNode" - nodeEventType = "switchNode"; - } else { - // 否则查找包含特定属性的DOM元素,并设置节点事件类型为clickNode - tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - if (tmp) { - // 获取主DOM元素的ID并赋值给tId - tId = tools.getNodeMainDom(tmp).id; - // 设置节点事件类型为"clickNode" - nodeEventType = "clickNode"; - } - } - } else if (tools.eqs(event.type, "dblclick")) { - // 双击事件处理,设置树事件类型为dblclick - treeEventType = "dblclick"; - // 获取目标元素中包含特定属性的子元素 - tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - if (tmp) { - // 获取节点的主DOM元素的ID - tId = tools.getNodeMainDom(tmp).id; - // 设置节点事件类型为switchNode - nodeEventType = "switchNode"; - } - } - // 检查treeEventType数组是否有元素且tId字符串是否为空 - if (treeEventType.length > 0 && tId.length == 0) { - // 调用tools.getMDom方法,获取目标元素的子元素,该子元素具有指定的标签名和属性名 - tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - // 如果找到了符合条件的元素 - if (tmp) { - // 获取该元素的主DOM节点的ID并赋值给tId - tId = tools.getNodeMainDom(tmp).id; - } - } - // event to node - if (tId.length > 0) { - // 获取节点缓存 - node = data.getNodeCache(setting, tId); - - // 根据节点事件类型进行处理 - switch (nodeEventType) { - case "switchNode" : - // 判断节点是否为父节点 - var isParent = data.nodeIsParent(setting, node); - if (!isParent) { - // 如果不是父节点,则清空事件类型 - nodeEventType = ""; - } else if (tools.eqs(event.type, "click") - || (tools.eqs(event.type, "dblclick") && tools.apply(setting.view.dblClickExpand, [setting.treeId, node], setting.view.dblClickExpand))) { - // 如果事件类型是点击或双击且满足展开条件,设置回调函数为切换节点处理函数 - nodeEventCallback = handler.onSwitchNode; - } else { - // 否则清空事件类型 - nodeEventType = ""; - } - break; - case "clickNode" : - // 如果事件类型是点击节点,设置回调函数为点击节点处理函数 - nodeEventCallback = handler.onClickNode; - break; - } - } - // event to zTree - switch (treeEventType) { - // 当事件类型为 "mousedown" 时,将 treeEventCallback 设置为 handler.onZTreeMousedown - case "mousedown" : - treeEventCallback = handler.onZTreeMousedown; - break; - // 当事件类型为 "mouseup" 时,将 treeEventCallback 设置为 handler.onZTreeMouseup - case "mouseup" : - treeEventCallback = handler.onZTreeMouseup; - break; - // 当事件类型为 "dblclick" 时,将 treeEventCallback 设置为 handler.onZTreeDblclick - case "dblclick" : - treeEventCallback = handler.onZTreeDblclick; - break; - // 当事件类型为 "contextmenu" 时,将 treeEventCallback 设置为 handler.onZTreeContextmenu - case "contextmenu" : - treeEventCallback = handler.onZTreeContextmenu; - break; - } - var proxyResult = { - // 停止标志,初始值为false - stop: false, - // 当前节点对象 - node: node, - // 节点事件类型 - nodeEventType: nodeEventType, - // 节点事件回调函数 - nodeEventCallback: nodeEventCallback, - // 树事件类型 - treeEventType: treeEventType, - // 树事件回调函数 - treeEventCallback: treeEventCallback - }; - // 返回代理结果对象 - return proxyResult - }, - //default init node of core - _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { - // 如果节点不存在,直接返回 - if (!n) return; - - // 获取树的根节点 - var r = data.getRoot(setting), - // 获取当前节点的子节点 - children = data.nodeChildren(setting, n); - - // 设置当前节点的层级 - n.level = level; - - // 生成并设置当前节点的唯一标识符 - n.tId = setting.treeId + "_" + (++r.zId); - - // 设置当前节点的父节点标识符 - n.parentTId = parentNode ? parentNode.tId : null; - - // 根据节点的open属性设置是否展开 - n.open = (typeof n.open == "string") ? tools.eqs(n.open, "true") : !!n.open; - - // 判断当前节点是否是父节点 - var isParent = data.nodeIsParent(setting, n); - - // 如果当前节点有子节点 - if (tools.isArray(children)) { - // 将当前节点标记为父节点 - data.nodeIsParent(setting, n, true); - // 标记当前节点为异步加载 - n.zAsync = true; - } else { - // 更新当前节点的父节点状态 - isParent = data.nodeIsParent(setting, n, isParent); - // 根据父节点状态和异步加载设置决定是否展开当前节点 - n.open = (isParent && !setting.async.enable) ? n.open : false; - // 标记当前节点为非异步加载 - n.zAsync = !isParent; - } - n.isFirstNode = isFirstNode; - // 设置节点是否为第一个节点的函数 - n.isLastNode = isLastNode; - // 设置节点是否为最后一个节点的函数 - n.getParentNode = function () { - return data.getNodeCache(setting, n.parentTId); - }; - // 获取父节点的方法,通过缓存获取父节点信息 - n.getPreNode = function () { - return data.getPreNode(setting, n); - }; - // 获取前一个兄弟节点的方法 - n.getNextNode = function () { - return data.getNextNode(setting, n); - }; - // 获取下一个兄弟节点的方法 - n.getIndex = function () { - return data.getNodeIndex(setting, n); - }; - // 获取当前节点在同级中的索引位置 - n.getPath = function () { - return data.getNodePath(setting, n); - }; - // 获取从根节点到当前节点的路径 - n.isAjaxing = false; - // 初始化节点的Ajax请求状态为false - data.fixPIdKeyValue(setting, n); - // 修正节点的父ID键值对 - }, - _init = { - bind: [_bindEvent], - // 绑定事件的方法数组 - unbind: [_unbindEvent], - // 解绑事件的方法数组 - caches: [_initCache], - // 初始化缓存的方法数组 - nodes: [_initNode], - // 初始化节点的方法数组 - proxys: [_eventProxy], - // 事件代理的方法数组 - roots: [_initRoot], - // 初始化根节点的方法数组 - beforeA: [], - // 在操作前的回调方法数组 - afterA: [], - // 在操作后的回调方法数组 - innerBeforeA: [], - // 内部操作前的回调方法数组 - innerAfterA: [], - // 内部操作后的回调方法数组 - zTreeTools: [] - // ZTree工具方法数组 - }, - //method of operate data - data = { - // 添加节点缓存 - addNodeCache: function (setting, node) { - // 获取指定设置的缓存,并将节点添加到缓存中 - data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node; - }, - // 获取节点缓存ID - getNodeCacheId: function (tId) { - // 返回节点ID的最后一部分作为缓存ID - return tId.substring(tId.lastIndexOf("_") + 1); - }, - // 添加afterA事件 - addAfterA: function (afterA) { - // 将afterA事件添加到初始化配置的afterA数组中 - _init.afterA.push(afterA); - }, - // 添加beforeA事件 - addBeforeA: function (beforeA) { - // 将beforeA事件添加到初始化配置的beforeA数组中 - _init.beforeA.push(beforeA); - }, - // 添加innerAfterA事件 - addInnerAfterA: function (innerAfterA) { - // 将innerAfterA事件添加到初始化配置的innerAfterA数组中 - _init.innerAfterA.push(innerAfterA); - }, - // 添加innerBeforeA事件 - addInnerBeforeA: function (innerBeforeA) { - // 将innerBeforeA事件添加到初始化配置的innerBeforeA数组中 - _init.innerBeforeA.push(innerBeforeA); - }, - // 添加初始化绑定事件 - addInitBind: function (bindEvent) { - // 将绑定事件添加到初始化配置的bind数组中 - _init.bind.push(bindEvent); - }, - // 添加初始化解绑事件 - addInitUnBind: function (unbindEvent) { - // 将解绑事件添加到初始化配置的unbind数组中 - _init.unbind.push(unbindEvent); - }, - // 添加初始化缓存 - addInitCache: function (initCache) { - // 将初始化缓存添加到初始化配置的caches数组中 - _init.caches.push(initCache); - }, - // 添加初始化节点 - addInitNode: function (initNode) { - // 将初始化节点添加到初始化配置的nodes数组中 - _init.nodes.push(initNode); - }, - // 添加初始化代理 - addInitProxy: function (initProxy, isFirst) { - if (!!isFirst) { - // 如果isFirst为真,将代理插入到proxys数组的开头 - _init.proxys.splice(0, 0, initProxy); - } else { - // 否则,将代理添加到proxys数组的末尾 - _init.proxys.push(initProxy); - } - }, - addInitRoot: function (initRoot) { - // 将初始化根节点添加到_init.roots数组中 - _init.roots.push(initRoot); - }, - addNodesData: function (setting, parentNode, index, nodes) { - // 获取父节点的子节点数据 - var children = data.nodeChildren(setting, parentNode), params; - // 如果父节点没有子节点 - if (!children) { - // 为父节点创建一个新的空子节点数组 - children = data.nodeChildren(setting, parentNode, []); - // 将索引设置为-1,表示插入位置无效 - index = -1; - } else if (index >= children.length) { - // 如果索引超出子节点数组的长度,将索引设置为-1 - index = -1; - } - - if (children.length > 0 && index === 0) { - // 如果子节点数组不为空且索引为0,则将第一个子节点的isFirstNode属性设置为false - children[0].isFirstNode = false; - // 设置第一个子节点的图标样式 - view.setNodeLineIcos(setting, children[0]); - } else if (children.length > 0 && index < 0) { - // 如果子节点数组不为空且索引小于0,则将最后一个子节点的isLastNode属性设置为false - children[children.length - 1].isLastNode = false; - // 设置最后一个子节点的图标样式 - view.setNodeLineIcos(setting, children[children.length - 1]); - } - // 设置父节点为父节点 - data.nodeIsParent(setting, parentNode, true); - - if (index < 0) { - // 如果索引小于0,则将新节点添加到子节点数组的末尾 - data.nodeChildren(setting, parentNode, children.concat(nodes)); - } else { - // 如果索引大于等于0,则在指定位置插入新节点 - params = [index, 0].concat(nodes); - children.splice.apply(children, params); - } - }, - addSelectedNode: function (setting, node) { - // 获取根节点 - var root = data.getRoot(setting); - // 如果节点未被选中,则将其添加到当前选中列表中 - if (!data.isSelectedNode(setting, node)) { - root.curSelectedList.push(node); - } - }, - addCreatedNode: function (setting, node) { - // 如果存在自定义的节点创建回调或添加自定义DOM的方法,则执行以下逻辑 - if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { - // 获取根节点 - var root = data.getRoot(setting); - // 将新创建的节点添加到已创建节点列表中 - root.createdNodes.push(node); - } - }, - addZTreeTools: function (zTreeTools) { - // 将传入的zTree工具对象添加到_init.zTreeTools数组中 - _init.zTreeTools.push(zTreeTools); - }, - exSetting: function (s) { - // 使用jQuery的extend方法,将传入的设置对象s合并到_setting对象中,实现深度拷贝 - $.extend(true, _setting, s); - }, - fixPIdKeyValue: function (setting, node) { - // 如果启用了简单数据模式 - if (setting.data.simpleData.enable) { - // 设置节点的父ID键值,如果节点有父节点则获取父节点的ID,否则设置为根节点的父ID - node[setting.data.simpleData.pIdKey] = node.parentTId ? node.getParentNode()[setting.data.simpleData.idKey] : setting.data.simpleData.rootPId; - } - }, - getAfterA: function (setting, node, array) { - // 遍历_init.afterA数组,并调用每个元素作为函数 - for (var i = 0, j = _init.afterA.length; i < j; i++) { - // 使用apply方法将当前上下文和参数传递给每个函数 - _init.afterA[i].apply(this, arguments); - } - }, - getBeforeA: function (setting, node, array) { - // 遍历_init.beforeA数组,并调用每个元素作为函数 - for (var i = 0, j = _init.beforeA.length; i < j; i++) { - // 使用apply方法将当前上下文和参数传递给每个函数 - _init.beforeA[i].apply(this, arguments); - } - }, - getInnerAfterA: function (setting, node, array) { - // 遍历_init.innerAfterA数组,并调用每个元素作为函数 - for (var i = 0, j = _init.innerAfterA.length; i < j; i++) { - // 使用apply方法将当前上下文和参数传递给每个函数 - _init.innerAfterA[i].apply(this, arguments); - } - }, - getInnerBeforeA: function (setting, node, array) { - // 遍历_init.innerBeforeA数组,并调用每个元素作为函数 - for (var i = 0, j = _init.innerBeforeA.length; i < j; i++) { - // 使用apply方法将当前上下文和参数传递给每个函数 - _init.innerBeforeA[i].apply(this, arguments); - } - }, - getCache: function (setting) { - // 返回缓存中对应treeId的缓存数据 - return caches[setting.treeId]; - }, - getNodeIndex: function (setting, node) { - // 如果节点为空,返回null - if (!node) return null; - // 获取父节点,如果节点没有父节点则获取根节点 - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - // 获取父节点的所有子节点 - children = data.nodeChildren(setting, p); - // 遍历子节点数组 - for (var i = 0, l = children.length - 1; i <= l; i++) { - // 如果找到匹配的节点,返回其索引 - if (children[i] === node) { - return i; - } - } - // 如果没有找到匹配的节点,返回-1 - return -1; - }, - getNextNode: function (setting, node) { - // 如果节点为空,返回null - if (!node) return null; - // 获取父节点,如果节点没有父节点则获取根节点 - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - // 获取父节点的所有子节点 - children = data.nodeChildren(setting, p); - // 遍历子节点数组 - for (var i = 0, l = children.length - 1; i <= l; i++) { - // 如果找到匹配的节点 - if (children[i] === node) { - // 如果是最后一个节点,返回null;否则返回下一个节点 - return (i == l ? null : children[i + 1]); - } - } - // 如果没有找到匹配的节点,返回null - return null; - }, - /** - * 根据指定的参数在节点数组中查找匹配的节点。 - * @param {Object} setting - 配置对象,用于获取子节点。 - * @param {Array} nodes - 要搜索的节点数组。 - * @param {String} key - 要匹配的键名。 - * @param {*} value - 要匹配的值。 - * @returns {Object|null} 返回匹配的节点,如果没有找到则返回null。 - */ - getNodeByParam: function (setting, nodes, key, value) { - // 如果节点数组或键名为空,直接返回null - if (!nodes || !key) return null; - // 遍历节点数组 - for (var i = 0, l = nodes.length; i < l; i++) { - // 获取当前节点 - var node = nodes[i]; - // 如果当前节点的指定键值与目标值相等,返回该节点 - if (node[key] == value) { - return nodes[i]; - } - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - // 递归调用自身在子节点中查找匹配的节点 - var tmp = data.getNodeByParam(setting, children, key, value); - // 如果找到匹配的节点,返回该节点 - if (tmp) return tmp; - } - // 如果未找到匹配的节点,返回null - return null; - }, - getNodeCache: function (setting, tId) { - // 如果tId不存在,返回null - if (!tId) return null; - // 从缓存中获取节点对象 - var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)]; - // 如果节点存在,返回节点;否则返回null - return n ? n : null; - }, - getNodePath: function (setting, node) { - // 如果node不存在,返回null - if (!node) return null; - - var path; - // 如果节点有父节点,递归获取父节点的路径 - if (node.parentTId) { - path = node.getParentNode().getPath(); - } else { - // 如果没有父节点,初始化路径为空数组 - path = []; - } - - // 如果路径存在,将当前节点添加到路径中 - if (path) { - path.push(node); - } - - // 返回节点路径 - return path; - }, - getNodes: function (setting) { - // 调用data.nodeChildren方法获取根节点的子节点 - return data.nodeChildren(setting, data.getRoot(setting)); - }, - getNodesByParam: function (setting, nodes, key, value) { - // 如果nodes或key为空,返回空数组 - if (!nodes || !key) return []; - var result = []; // 初始化结果数组 - // 遍历所有节点 - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; // 当前节点 - // 如果当前节点的指定属性值等于目标值,则将该节点加入结果数组 - if (node[key] == value) { - result.push(node); - } - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - // 递归查找子节点中符合条件的节点并合并到结果数组中 - result = result.concat(data.getNodesByParam(setting, children, key, value)); - } - // 返回符合条件的节点数组 - return result; - }, - getNodesByParamFuzzy: function (setting, nodes, key, value) { - // 如果节点或键为空,返回空数组 - if (!nodes || !key) return []; - - // 初始化结果数组 - var result = []; - - // 将搜索值转换为小写 - value = value.toLowerCase(); - - // 遍历所有节点 - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - - // 如果节点的指定键是字符串且包含搜索值,则将该节点加入结果数组 - if (typeof node[key] == "string" && nodes[i][key].toLowerCase().indexOf(value) > -1) { - result.push(node); - } - - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - - // 递归调用函数以查找子节点中的匹配项,并将结果合并到结果数组中 - result = result.concat(data.getNodesByParamFuzzy(setting, children, key, value)); - } - - // 返回最终的结果数组 - return result; - }, - /** - * 根据过滤条件获取节点 - * @param {Object} setting - 配置对象 - * @param {Array} nodes - 节点数组 - * @param {Function} filter - 过滤函数 - * @param {Boolean} isSingle - 是否只返回一个节点 - * @param {Any} invokeParam - 传递给过滤函数的参数 - * @returns {Array|null} 符合条件的节点数组或单个节点,如果没有符合条件的节点则返回空数组或null - */ - getNodesByFilter: function (setting, nodes, filter, isSingle, invokeParam) { - // 如果节点数组为空,根据isSingle决定返回null还是空数组 - if (!nodes) return (isSingle ? null : []); - - // 初始化结果变量,根据isSingle决定是null还是空数组 - var result = isSingle ? null : []; - - // 遍历所有节点 - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - - // 使用过滤函数检查当前节点是否符合条件 - if (tools.apply(filter, [node, invokeParam], false)) { - // 如果只需要一个节点且找到符合条件的节点,直接返回该节点 - if (isSingle) { - return node; - } - // 否则将符合条件的节点加入结果数组 - result.push(node); - } - - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - - // 递归调用自身以处理子节点 - var tmpResult = data.getNodesByFilter(setting, children, filter, isSingle, invokeParam); - - // 如果只需要一个节点且在子节点中找到符合条件的节点,直接返回该节点 - if (isSingle && !!tmpResult) { - return tmpResult; - } - - // 根据isSingle决定是替换结果还是合并结果 - result = isSingle ? tmpResult : result.concat(tmpResult); - } - - // 返回最终的结果数组或单个节点 - return result; - }, - getPreNode: function (setting, node) { - // 如果节点为空,返回null - if (!node) return null; - // 获取父节点,如果当前节点没有父节点则获取根节点 - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - // 获取父节点的子节点列表 - children = data.nodeChildren(setting, p); - // 遍历子节点列表 - for (var i = 0, l = children.length; i < l; i++) { - // 如果找到当前节点 - if (children[i] === node) { - // 返回前一个节点,如果是第一个节点则返回null - return (i == 0 ? null : children[i - 1]); - } - } - // 如果没有找到当前节点,返回null - return null; - }, - /** - * 获取树的根节点 - * @param {Object} setting - 配置对象 - * @returns {Object|null} 根节点或null - */ - getRoot: function (setting) { - // 根据配置对象的treeId获取根节点 - return setting ? roots[setting.treeId] : null; - }, - /** - * 获取所有树的根节点集合 - * @returns {Object} 根节点集合 - */ - getRoots: function () { - // 返回所有根节点的集合 - return roots; - }, - /** - * 获取指定树的配置对象 - * @param {string} treeId - 树的唯一标识符 - * @returns {Object|null} 配置对象或null - */ - getSetting: function (treeId) { - // 根据树的唯一标识符获取配置对象 - return settings[treeId]; - }, - /** - * 获取所有树的配置对象集合 - * @returns {Object} 配置对象集合 - */ - getSettings: function () { - // 返回所有配置对象的集合 - return settings; - }, - /** - * 获取指定树的工具对象 - * @param {string} treeId - 树的唯一标识符 - * @returns {Object|null} 工具对象或null - */ - getZTreeTools: function (treeId) { - // 根据树的唯一标识符获取根节点 - var r = this.getRoot(this.getSetting(treeId)); - // 返回根节点的工具对象,如果不存在则返回null - return r ? r.treeTools : null; - }, - /** - * 初始化缓存 - * @param {Object} setting - 配置对象 - */ - initCache: function (setting) { - // 遍历并应用所有缓存初始化函数 - for (var i = 0, j = _init.caches.length; i < j; i++) { - _init.caches[i].apply(this, arguments); - } - }, - /** - * 初始化节点 - * @param {Object} setting - 配置对象 - * @param {number} level - 节点层级 - * @param {Object} node - 当前节点 - * @param {Object} parentNode - 父节点 - * @param {Object} preNode - 前一个兄弟节点 - * @param {Object} nextNode - 后一个兄弟节点 - */ - initNode: function (setting, level, node, parentNode, preNode, nextNode) { - // 遍历并应用所有节点初始化函数 - for (var i = 0, j = _init.nodes.length; i < j; i++) { - _init.nodes[i].apply(this, arguments); - } - }, - initRoot: function (setting) { - // 遍历所有根节点初始化函数,并调用它们 - for (var i = 0, j = _init.roots.length; i < j; i++) { - _init.roots[i].apply(this, arguments); - } - }, - isSelectedNode: function (setting, node) { - // 获取当前设置的根节点 - var root = data.getRoot(setting); - // 遍历当前选中的节点列表,检查目标节点是否在其中 - for (var i = 0, j = root.curSelectedList.length; i < j; i++) { - if (node === root.curSelectedList[i]) return true; // 如果找到匹配的节点,返回true - } - return false; // 如果没有找到匹配的节点,返回false - }, - nodeChildren: function (setting, node, newChildren) { - if (!node) { - return null; // 如果节点不存在,返回null - } - var key = setting.data.key.children; // 获取子节点的键名 - if (typeof newChildren !== 'undefined') { - node[key] = newChildren; // 如果提供了新的子节点,更新节点的子节点 - } - return node[key]; // 返回节点的子节点 - }, - nodeIsParent: function (setting, node, newIsParent) { - if (!node) { - return false; // 如果节点不存在,返回false - } - var key = setting.data.key.isParent; - // 检查 newIsParent 是否定义 - if (typeof newIsParent !== 'undefined') { - // 如果 newIsParent 是字符串类型,则将其与 "true" 比较并转换为布尔值 - if (typeof newIsParent === "string") { - newIsParent = tools.eqs(newIsParent, "true"); - } - // 将 newIsParent 转换为布尔值并赋值给 node[key] - newIsParent = !!newIsParent; - node[key] = newIsParent; - } else if (typeof node[key] == "string"){ - // 如果 node[key] 是字符串类型,则将其与 "true" 比较并转换为布尔值 - node[key] = tools.eqs(node[key], "true"); - } else { - // 将 node[key] 转换为布尔值 - node[key] = !!node[key]; - } - // 返回 node[key] 的布尔值 - return node[key]; - }, - /** - * 设置或获取节点的名称 - * @param {Object} setting - 配置对象 - * @param {Object} node - 节点对象 - * @param {String} [newName] - 新的节点名称(可选) - * @returns {String} - 节点名称 - */ - nodeName: function (setting, node, newName) { - // 获取节点名称的键名 - var key = setting.data.key.name; - // 如果 newName 已定义,则更新节点名称 - if (typeof newName !== 'undefined') { - node[key] = newName; - } - // 将节点名称转换为字符串 - var rawName = "" + node[key]; - // 如果 render.name 是一个函数,则调用该函数并返回结果 - if(typeof setting.data.render.name === 'function') { - return setting.data.render.name.call(this,rawName,node); - } - // 否则直接返回原始名称 - return rawName; - }, - nodeTitle: function (setting, node) { - // 获取节点标题,如果标题为空则使用名称 - var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title; - // 将节点的标题转换为字符串 - var rawTitle = "" + node[t]; - // 如果设置了自定义渲染函数,则调用该函数渲染标题 - if(typeof setting.data.render.title === 'function') { - return setting.data.render.title.call(this,rawTitle,node); - } - // 返回原始标题 - return rawTitle; - }, - removeNodeCache: function (setting, node) { - // 获取节点的子节点 - var children = data.nodeChildren(setting, node); - // 如果存在子节点,递归删除每个子节点的缓存 - if (children) { - for (var i = 0, l = children.length; i < l; i++) { - data.removeNodeCache(setting, children[i]); - } - } - // 将当前节点的缓存设置为null - data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null; - }, - removeSelectedNode: function (setting, node) { - // 获取树的根节点 - var root = data.getRoot(setting); - // 遍历当前选中的节点列表 - for (var i = 0, j = root.curSelectedList.length; i < j; i++) { - // 如果当前节点在选中列表中或其缓存不存在,则从选中列表中移除 - if (node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) { - root.curSelectedList.splice(i, 1); - // 触发取消选中事件 - setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, node]); - // 调整索引以反映已移除的元素 - i--; - j--; - } - } - }, - setCache: function (setting, cache) { - // 将缓存对象存储到caches数组中,键为treeId - caches[setting.treeId] = cache; - }, - setRoot: function (setting, root) { - // 将根节点对象存储到roots数组中,键为treeId - roots[setting.treeId] = root; - }, - setZTreeTools: function (setting, zTreeTools) { - // 遍历_init.zTreeTools数组并调用每个工具函数,传递当前上下文和参数 - for (var i = 0, j = _init.zTreeTools.length; i < j; i++) { - _init.zTreeTools[i].apply(this, arguments); - } - }, - transformToArrayFormat: function (setting, nodes) { - // 如果nodes为空,返回空数组 - if (!nodes) return []; - // 初始化结果数组r - var r = []; - // 如果nodes是数组,则遍历每个节点并调用_do函数处理 - if (tools.isArray(nodes)) { - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - _do(node); - } - } else { - // 如果nodes不是数组,直接调用_do函数处理 - _do(nodes); - } - // 返回结果数组r - return r; - - function _do(_node) { - // 将当前节点添加到结果数组中 - r.push(_node); - - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, _node); - - // 如果存在子节点,则将其转换为数组格式并合并到结果数组中 - if (children) { - r = r.concat(data.transformToArrayFormat(setting, children)); - } - } - }, - transformTozTreeFormat: function (setting, sNodes) { - // 定义变量i和l,用于循环控制 - var i, l, - // 获取节点ID的键名 - key = setting.data.simpleData.idKey, - // 获取父节点ID的键名 - parentKey = setting.data.simpleData.pIdKey; - // 如果key为空或sNodes不存在,返回空数组 - if (!key || key == "" || !sNodes) return []; - - // 如果sNodes是数组类型 - if (tools.isArray(sNodes)) { - // 初始化结果数组r - var r = []; - // 初始化临时映射对象tmpMap - var tmpMap = {}; - // 遍历sNodes数组 - for (i = 0, l = sNodes.length; i < l; i++) { - // 将每个节点按其ID存入tmpMap中 - tmpMap[sNodes[i][key]] = sNodes[i]; - } - // 遍历sNodes数组中的每一个元素 - for (i = 0, l = sNodes.length; i < l; i++) { - // 获取当前节点的父节点在tmpMap中的引用 - var p = tmpMap[sNodes[i][parentKey]]; - // 如果父节点存在且当前节点不是其父节点 - if (p && sNodes[i][key] != sNodes[i][parentKey]) { - // 获取父节点的子节点列表 - var children = data.nodeChildren(setting, p); - // 如果父节点没有子节点列表,则初始化一个空列表 - if (!children) { - children = data.nodeChildren(setting, p, []); - } - // 将当前节点添加到父节点的子节点列表中 - children.push(sNodes[i]); - } else { - // 如果父节点不存在或当前节点是其父节点,则将当前节点添加到结果数组r中 - r.push(sNodes[i]); - } - } - // 如果条件满足,返回变量r - return r; -} else { - // 如果条件不满足,返回包含sNodes的数组 - return [sNodes]; -} - } - }, - //method of event proxy - event = { - // 绑定事件的方法,接受一个设置参数 - bindEvent: function (setting) { - // 遍历_init.bind数组中的每一个元素 - for (var i = 0, j = _init.bind.length; i < j; i++) { - // 调用当前元素的apply方法,将当前上下文和传入的参数传递给它 - _init.bind[i].apply(this, arguments); - } - }, - unbindEvent: function (setting) { - // 遍历_init.unbind数组,并调用每个元素的apply方法,将当前上下文和参数传递给它 - for (var i = 0, j = _init.unbind.length; i < j; i++) { - _init.unbind[i].apply(this, arguments); - } - }, - bindTree: function (setting) { - // 创建一个包含treeId属性的对象eventParam - var eventParam = { - treeId: setting.treeId - }, - // 获取树对象 - o = setting.treeObj; - // 如果视图中不允许选择文本 - if (!setting.view.txtSelectedEnable) { - // 绑定selectstart事件处理程序,防止文本被选中,并设置CSS样式以禁用文本选择 - o.bind('selectstart', handler.onSelectStart).css({ - "-moz-user-select": "-moz-none" - }); - } - // 绑定点击事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('click', eventParam, event.proxy); - // 绑定双击事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('dblclick', eventParam, event.proxy); - // 绑定鼠标悬停事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('mouseover', eventParam, event.proxy); - // 绑定鼠标移出事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('mouseout', eventParam, event.proxy); - // 绑定鼠标按下事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('mousedown', eventParam, event.proxy); - // 绑定鼠标抬起事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('mouseup', eventParam, event.proxy); - // 绑定右键菜单事件到对象o,并使用event.proxy作为事件处理函数 - o.bind('contextmenu', eventParam, event.proxy); - unbindTree: function (setting) { - // 获取树形对象的引用 - var o = setting.treeObj; - // 解绑'selectstart'事件,防止文本选择 - o.unbind('selectstart', handler.onSelectStart) - // 解绑'click'事件,取消点击事件的代理处理 - .unbind('click', event.proxy) - // 解绑'dblclick'事件,取消双击事件的代理处理 - .unbind('dblclick', event.proxy) - // 解绑'mouseover'事件,取消鼠标悬停事件的代理处理 - .unbind('mouseover', event.proxy) - // 解绑'mouseout'事件,取消鼠标移出事件的代理处理 - .unbind('mouseout', event.proxy) - // 解绑'mousedown'事件,取消鼠标按下事件的代理处理 - .unbind('mousedown', event.proxy) - // 解绑'mouseup'事件,取消鼠标抬起事件的代理处理 - .unbind('mouseup', event.proxy) - // 解绑'contextmenu'事件,取消右键菜单事件的代理处理 - .unbind('contextmenu', event.proxy); - }, - doProxy: function (e) { - // 初始化一个空数组,用于存储代理函数的返回结果 - var results = []; - // 遍历所有代理函数 - for (var i = 0, j = _init.proxys.length; i < j; i++) { - // 调用当前代理函数,并将结果存储在proxyResult中 - var proxyResult = _init.proxys[i].apply(this, arguments); - // 将当前代理函数的结果添加到results数组中 - results.push(proxyResult); - // 如果当前代理函数的返回结果包含stop属性且为true,则中断循环 - if (proxyResult.stop) { - break; - } - } - // 返回所有代理函数的结果数组 - return results; - }, - proxy: function (e) { - // 获取当前树的设置信息 - var setting = data.getSetting(e.data.treeId); - - // 检查用户是否有权限执行该操作,如果没有权限则返回true - if (!tools.uCanDo(setting, e)) return true; - - // 执行代理事件并获取结果数组 - var results = event.doProxy(e), - r = true, // 初始化返回值为true - x = false; // 初始化标志位为false - - // 遍历所有代理结果 - for (var i = 0, l = results.length; i < l; i++) { - var proxyResult = results[i]; - - // 如果存在节点事件回调函数,则调用它并更新返回值和标志位 - if (proxyResult.nodeEventCallback) { - x = true; - r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; - } - - // 如果存在树事件回调函数,则调用它并更新返回值和标志位 - if (proxyResult.treeEventCallback) { - x = true; - r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; - } - } - - // 返回最终的结果值 - return r; - } - }, - //method of event handler - handler = { - // 处理节点切换事件的方法 - onSwitchNode: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - - // 如果节点是展开状态 - if (node.open) { - // 调用回调函数,判断是否允许折叠节点,如果返回false则终止操作 - if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) return true; - - // 设置根节点的expandTriggerFlag为true,表示触发了展开操作 - data.getRoot(setting).expandTriggerFlag = true; - - // 切换节点的状态(从展开到折叠) - view.switchNode(setting, node); - } else { - // 调用回调函数,判断是否允许展开节点,如果返回false则终止操作 - if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true; - - // 设置根节点的expandTriggerFlag为true,表示触发了展开操作 - data.getRoot(setting).expandTriggerFlag = true; - - // 切换节点的状态(从折叠到展开) - view.switchNode(setting, node); - } - - // 返回true表示操作成功 - return true; - }, - /** - * 处理节点点击事件的函数 - * @param {Object} event - 事件对象,包含触发事件的信息 - * @param {Object} node - 被点击的节点对象 - */ - onClickNode: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId), - // 根据是否按下Ctrl或Meta键以及节点是否已选中来确定点击标志 - clickFlag = ((setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey)) && data.isSelectedNode(setting, node)) ? 0 : (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey) && setting.view.selectedMulti) ? 2 : 1; - // 如果beforeClick回调函数返回false,则终止执行并返回true - if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) return true; - // 如果点击标志为0,取消之前选中的节点 - if (clickFlag === 0) { - view.cancelPreSelectedNode(setting, node); - } else { - // 否则根据点击标志选择或取消选择节点 - view.selectNode(setting, node, clickFlag === 2); - } - // 触发CLICK事件,传递事件对象、树ID、节点和点击标志 - setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]); - // 返回true表示事件处理完成 - return true; - }, - onZTreeMousedown: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - // 在鼠标按下事件之前执行回调函数,如果返回true则继续执行后续操作 - if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) { - // 执行鼠标按下事件的回调函数 - tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]); - } - return true; // 始终返回true,表示事件处理完成 - }, - onZTreeMouseup: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - // 在鼠标抬起事件之前执行回调函数,如果返回true则继续执行后续操作 - if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) { - // 执行鼠标抬起事件的回调函数 - tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]); - } - return true; // 始终返回true,表示事件处理完成 - }, - onZTreeDblclick: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - // 在双击事件之前执行回调函数,如果返回true则继续执行后续操作 - if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) { - // 执行双击事件的回调函数 - tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]); - } - return true; // 始终返回true,表示事件处理完成 - }, - onZTreeContextmenu: function (event, node) { - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - // 在右键点击事件之前执行回调函数,如果返回true则继续执行后续操作 - if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) { - // 执行右键点击事件的回调函数 - tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]); - } - // 检查是否有定义右键点击的回调函数,如果没有则返回false - return (typeof setting.callback.onRightClick) != "function"; - }, - onSelectStart: function (e) { - // 获取触发事件的元素节点名称并转换为小写 - var n = e.originalEvent.srcElement.nodeName.toLowerCase(); - // 如果元素是input或textarea,则允许选择文本 - return (n === "input" || n === "textarea"); - } - }, - //method of tools for zTree - tools = { - /** - * 应用函数,如果传入的参数是函数则调用该函数并返回结果,否则返回默认值。 - * @param {Function} fun - 要应用的函数 - * @param {Array} param - 函数参数数组 - * @param {*} defaultValue - 默认值 - * @returns {*} 函数执行结果或默认值 - */ - apply: function (fun, param, defaultValue) { - if ((typeof fun) == "function") { - // 如果fun是函数,则使用apply方法调用它 - return fun.apply(zt, param ? param : []); - } - // 如果fun不是函数,返回默认值 - return defaultValue; - }, - /** - * 判断节点是否可以异步加载子节点。 - * @param {Object} setting - 配置对象 - * @param {Object} node - 当前节点 - * @returns {boolean} 是否可以异步加载子节点 - */ - canAsync: function (setting, node) { - // 获取节点的子节点 - var children = data.nodeChildren(setting, node); - // 判断节点是否是父节点 - var isParent = data.nodeIsParent(setting, node); - // 判断是否启用了异步加载,并且节点存在且是父节点,同时没有异步标记且没有子节点 - return (setting.async.enable && node && isParent && !(node.zAsync || (children && children.length > 0))); - }, - /** - * 深度克隆一个对象。 - * @param {Object} obj - 要克隆的对象 - * @returns {Object} 克隆后的新对象 - */ - clone: function (obj) { - if (obj === null) return null; // 如果对象为null,直接返回null - // 根据对象类型创建新对象 - var o = tools.isArray(obj) ? [] : {}; - for (var i in obj) { - // 递归克隆对象属性 - o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? tools.clone(obj[i]) : obj[i]); - } - return o; // 返回克隆后的对象 - }, - /** - * 比较两个字符串是否相等(忽略大小写)。 - * @param {string} str1 - 第一个字符串 - * @param {string} str2 - 第二个字符串 - * @returns {boolean} 字符串是否相等 - */ - eqs: function (str1, str2) { - return str1.toLowerCase() === str2.toLowerCase(); // 转换为小写后比较 - }, - /** - * 判断一个对象是否是数组。 - * @param {Object} arr - 要判断的对象 - * @returns {boolean} 是否是数组 - */ - isArray: function (arr) { - return Object.prototype.toString.apply(arr) === "[object Array]"; // 通过原型链判断是否为数组 - }, - /** - * 判断一个对象是否是HTML元素。 - * @param {Object} o - 要判断的对象 - * @returns {boolean} 是否是HTML元素 - */ - isElement: function (o) { - return ( - typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2 - o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string" //DOM3 - ); - }, - $: function (node, exp, setting) { - // 检查exp是否存在且不是字符串类型 - if (!!exp && typeof exp != "string") { - // 如果exp存在且不是字符串,则将setting赋值为exp,并将exp置为空字符串 - setting = exp; - exp = ""; - } - // 检查node是否为字符串类型 - if (typeof node == "string") { - // 如果node是字符串,则根据setting中的treeObj获取文档对象并返回相应的jQuery对象 - return $(node, setting ? setting.treeObj.get(0).ownerDocument : null); - } else { - // 如果node不是字符串,则根据node的tId和exp构建选择器,并根据setting中的treeObj返回相应的jQuery对象 - return $("#" + node.tId + exp, setting ? setting.treeObj : null); - } - }, - getMDom: function (setting, curDom, targetExpr) { - // 如果当前DOM节点为空,返回null - if (!curDom) return null; - // 循环遍历父节点直到找到匹配的树ID或到达根节点 - while (curDom && curDom.id !== setting.treeId) { - // 遍历目标表达式数组 - for (var i = 0, l = targetExpr.length; curDom.tagName && i < l; i++) { - // 检查当前DOM节点的标签名和属性是否匹配目标表达式 - if (tools.eqs(curDom.tagName, targetExpr[i].tagName) && curDom.getAttribute(targetExpr[i].attrName) !== null) { - // 如果匹配,返回当前DOM节点 - return curDom; - } - } - // 移动到父节点继续检查 - curDom = curDom.parentNode; - } - // 如果没有找到匹配的节点,返回null - return null; - }, - - getNodeMainDom: function (target) { - // 获取目标元素的父级
  • 元素,如果不存在则获取最近的祖先
  • 元素 - return ($(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0)); - }, - - isChildOrSelf: function (dom, parentId) { - // 判断给定的DOM节点是否是指定父节点的子节点或自身 - return ($(dom).closest("#" + parentId).length > 0); - }, - - uCanDo: function (setting, e) { - // 默认返回true,表示可以执行操作 - return true; - } - //method of operate ztree dom - view = { - // 添加节点的方法 - addNodes: function (setting, parentNode, index, newNodes, isSilent) { - // 判断父节点是否是父节点类型 - var isParent = data.nodeIsParent(setting, parentNode); - // 如果配置中要求保持叶子节点,并且父节点存在且不是父节点类型,则直接返回 - if (setting.data.keep.leaf && parentNode && !isParent) { - return; - } - // 如果新节点不是数组,则将其转换为数组 - if (!tools.isArray(newNodes)) { - newNodes = [newNodes]; - } - // 如果启用了简单数据格式,则将新节点转换为zTree格式 - if (setting.data.simpleData.enable) { - newNodes = data.transformTozTreeFormat(setting, newNodes); - } - // 如果父节点存在 - if (parentNode) { - // 获取父节点的开关对象、图标对象和子节点容器对象 - var target_switchObj = $$(parentNode, consts.id.SWITCH, setting), - target_icoObj = $$(parentNode, consts.id.ICON, setting), - target_ulObj = $$(parentNode, consts.id.UL, setting); - - // 如果父节点未打开 - if (!parentNode.open) { - // 替换父节点的开关类为关闭状态 - view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE); - // 替换父节点的图标类为关闭状态 - view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE); - // 设置父节点为关闭状态 - parentNode.open = false; - // 隐藏父节点的子节点容器 - target_ulObj.css({ - "display": "none" - }); - } - - data.addNodesData(setting, parentNode, index, newNodes); - // 将新节点数据添加到父节点中 - view.createNodes(setting, parentNode.level + 1, newNodes, parentNode, index); - // 创建并显示新节点,设置其层级为父节点的层级加一 - if (!isSilent) { - view.expandCollapseParentNode(setting, parentNode, true); - } - // 如果不需要静默处理,则展开父节点以显示新添加的子节点 - } else { - data.addNodesData(setting, data.getRoot(setting), index, newNodes); - // 如果没有父节点,则将新节点数据添加到根节点中 - view.createNodes(setting, 0, newNodes, null, index); - // 创建并显示新节点,设置其层级为0(根节点) - } - }, - appendNodes: function (setting, level, nodes, parentNode, index, initFlag, openFlag) { - if (!nodes) return []; - // 如果节点列表为空,返回空数组 - var html = []; - // 初始化HTML数组,用于存储生成的HTML代码片段 - var tmpPNode = (parentNode) ? parentNode : data.getRoot(setting), - // 获取父节点,如果未指定父节点,则使用根节点 - tmpPChild = data.nodeChildren(setting, tmpPNode), - // 获取父节点的子节点列表 - isFirstNode, isLastNode; - // 定义两个变量,用于标记是否是第一个或最后一个节点 - - if (!tmpPChild || index >= tmpPChild.length - nodes.length) { - index = -1; - } - // 如果父节点没有子节点,或者索引超出范围,则将索引设置为-1,表示在末尾追加节点 - - // 遍历节点数组 - for (var i = 0, l = nodes.length; i < l; i++) { - // 获取当前节点 - var node = nodes[i]; - // 如果初始化标志为真 - if (initFlag) { - // 判断是否为第一个节点 - isFirstNode = ((index === 0 || tmpPChild.length == nodes.length) && (i == 0)); - // 判断是否为最后一个节点 - isLastNode = (index < 0 && i == (nodes.length - 1)); - // 初始化节点 - data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); - // 将节点添加到缓存中 - data.addNodeCache(setting, node); - } - // 检查节点是否为父节点 - var isParent = data.nodeIsParent(setting, node); - - // 存储子节点的HTML内容 - var childHtml = []; - // 获取子节点 - var children = data.nodeChildren(setting, node); - // 如果存在子节点 - if (children && children.length > 0) { - // 先生成子节点的HTML,因为需要检查类型 - childHtml = view.appendNodes(setting, level + 1, children, node, -1, initFlag, openFlag && node.open); - } - // 如果打开标志为真 - if (openFlag) { - // 生成主节点前的DOM结构 - view.makeDOMNodeMainBefore(html, setting, node); - // 生成节点连接线 - view.makeDOMNodeLine(html, setting, node); - // 获取节点前的内容 - data.getBeforeA(setting, node, html); - // 生成节点名称前的DOM结构 - view.makeDOMNodeNameBefore(html, setting, node); - // 获取节点内部前的内容 - data.getInnerBeforeA(setting, node, html); - // 生成节点图标 - view.makeDOMNodeIcon(html, setting, node); - // 获取节点内部后的内容 - data.getInnerAfterA(setting, node, html); - // 生成节点名称后的DOM结构 - view.makeDOMNodeNameAfter(html, setting, node); - // 获取节点后的内容 - data.getAfterA(setting, node, html); - // 如果节点是父节点且已打开 - if (isParent && node.open) { - // 生成包含子节点的UL HTML结构 - view.makeUlHtml(setting, node, html, childHtml.join('')); - } - // 生成主节点后的DOM结构 - view.makeDOMNodeMainAfter(html, setting, node); - // 将创建的节点添加到已创建节点列表中 - data.addCreatedNode(setting, node); - } - } - return html; - }, - /** - * 将父节点的UL DOM元素追加到指定的节点上 - * @param {Object} setting - 配置对象 - * @param {Object} node - 当前节点对象 - */ - appendParentULDom: function (setting, node) { - // 初始化HTML数组 - var html = [], - // 获取当前节点对应的jQuery对象 - nObj = $$(node, setting); - // 如果当前节点不存在且有父节点ID,则递归调用自身 - if (!nObj.get(0) && !!node.parentTId) { - view.appendParentULDom(setting, node.getParentNode()); - nObj = $$(node, setting); - } - // 获取当前节点对应的UL jQuery对象 - var ulObj = $$(node, consts.id.UL, setting); - // 如果UL对象存在,则移除它 - if (ulObj.get(0)) { - ulObj.remove(); - } - // 获取子节点数据 - var children = data.nodeChildren(setting, node), - // 生成子节点的HTML内容 - childHtml = view.appendNodes(setting, node.level + 1, children, node, -1, false, true); - // 生成UL HTML内容并追加到html数组中 - view.makeUlHtml(setting, node, html, childHtml.join('')); - // 将生成的HTML内容追加到当前节点对象中 - nObj.append(html.join('')); - }, - /** - * 异步加载节点数据 - * @param {Object} setting - 配置对象 - * @param {Object} node - 当前节点对象 - * @param {Boolean} isSilent - 是否静默加载 - * @param {Function} callback - 回调函数 - */ - asyncNode: function (setting, node, isSilent, callback) { - var i, l; - // 判断当前节点是否是父节点 - var isParent = data.nodeIsParent(setting, node); - // 如果当前节点不是父节点,直接执行回调函数并返回false - if (node && !isParent) { - tools.apply(callback); - return false; - // 如果当前节点正在异步加载,直接返回false - } else if (node && node.isAjaxing) { - return false; - // 如果beforeAsync回调函数返回false,则执行回调函数并返回false - } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) { - tools.apply(callback); - return false; - } - if (node) { - // 如果节点存在,设置节点的isAjaxing属性为true,表示该节点正在进行异步请求 - node.isAjaxing = true; - // 获取节点对应的图标对象 - var icoObj = $$(node, consts.id.ICON, setting); - // 更新图标对象的样式和类名,显示加载中的动画效果 - icoObj.attr({"style": "", "class": consts.className.BUTTON + " " + consts.className.ICO_LOADING}); - } - - // 初始化一个空对象,用于存储参数 - var tmpParam = {}; - // 调用工具函数生成自动参数数组 - var autoParam = tools.apply(setting.async.autoParam, [setting.treeId, node], setting.async.autoParam); - // 遍历自动参数数组 - for (i = 0, l = autoParam.length; node && i < l; i++) { - // 将每个参数按等号分割成键值对 - var pKey = autoParam[i].split("="), spKey = pKey; - if (pKey.length > 1) { - // 如果参数包含等号,则取等号后面的部分作为键 - spKey = pKey[1]; - // 取等号前面的部分作为值 - pKey = pKey[0]; - } - // 将节点的对应属性值赋给临时参数对象 - tmpParam[spKey] = node[pKey]; - } - // 调用工具函数生成其他参数数组 - var otherParam = tools.apply(setting.async.otherParam, [setting.treeId, node], setting.async.otherParam); - // 如果其他参数是数组形式 - if (tools.isArray(otherParam)) { - // 遍历数组,以键值对的形式添加到临时参数对象中 - for (i = 0, l = otherParam.length; i < l; i += 2) { - tmpParam[otherParam[i]] = otherParam[i + 1]; - } - } else { - // 如果其他参数是对象形式 - // 遍历对象,将每个属性添加到临时参数对象中 - for (var p in otherParam) { - tmpParam[p] = otherParam[p]; - } - } - - // 获取当前根节点的版本号 - var _tmpV = data.getRoot(setting)._ver; - - // 发起异步请求 - $.ajax({ - // 设置请求的内容类型 - contentType: setting.async.contentType, - // 禁用缓存 - cache: false, - // 设置请求的类型(GET、POST等) - type: setting.async.type, - // 生成请求的URL,使用工具函数处理模板字符串 - url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url), - // 根据内容类型决定发送的数据格式 - data: setting.async.contentType.indexOf('application/json') > -1 ? JSON.stringify(tmpParam) : tmpParam, - // 设置期望的响应数据类型 - dataType: setting.async.dataType, - // 设置请求头信息 - headers: setting.async.headers, - // 设置XHR字段 - xhrFields: setting.async.xhrFields, - // 请求成功时的回调函数 - success: function (msg) { - // 如果版本号发生变化,则直接返回,不进行后续处理 - if (_tmpV != data.getRoot(setting)._ver) { - return; - } - // 初始化新节点数组 - var newNodes = []; - try { - // 如果响应为空或长度为0,则新节点数组为空 - if (!msg || msg.length == 0) { - newNodes = []; - // 如果响应是字符串,则尝试解析为JSON对象 - } else if (typeof msg == "string") { - newNodes = eval("(" + msg + ")"); - // 否则直接将响应赋值给新节点数组 - } else { - newNodes = msg; - } - } catch (err) { - // 如果解析过程中发生错误,则将原始响应赋值给新节点数组 - newNodes = msg; - } - - if (node) { - // 将节点的isAjaxing属性设置为null,表示该节点不再进行异步操作 - node.isAjaxing = null; - // 设置节点的zAsync属性为true,表示该节点是异步加载的 - node.zAsync = true; - } - // 更新节点的图标和线条样式 - view.setNodeLineIcos(setting, node); - if (newNodes && newNodes !== "") { - // 应用数据过滤器处理新节点数据 - newNodes = tools.apply(setting.async.dataFilter, [setting.treeId, node, newNodes], newNodes); - // 添加新节点到视图中 - view.addNodes(setting, node, -1, !!newNodes ? tools.clone(newNodes) : [], !!isSilent); - } else { - // 如果新节点数据为空,则添加空数组作为新节点 - view.addNodes(setting, node, -1, [], !!isSilent); - } - // 触发异步成功事件 - setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]); - // 执行回调函数 - tools.apply(callback); - }, - error: function (XMLHttpRequest, textStatus, errorThrown) { - // 如果版本号不一致,直接返回 - if (_tmpV != data.getRoot(setting)._ver) { - return; - } - // 将节点的isAjaxing属性设置为null,表示该节点不再进行异步操作 - if (node) node.isAjaxing = null; - // 更新节点的图标和线条样式 - view.setNodeLineIcos(setting, node); - // 触发异步错误事件 - setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]); - } - }, - return true; - }, - cancelPreSelectedNode: function (setting, node, excludeNode) { - // 获取当前选中的节点列表 - var list = data.getRoot(setting).curSelectedList, - i, n; - // 从后向前遍历选中的节点列表 - for (i = list.length - 1; i >= 0; i--) { - n = list[i]; - // 如果当前节点是需要取消选中的节点或排除节点,则进行处理 - if (node === n || (!node && (!excludeNode || excludeNode !== n))) { - // 移除节点的选中样式 - $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED); - if (node) { - // 从选中列表中移除该节点 - data.removeSelectedNode(setting, node); - break; - } else { - // 从选中列表中删除该节点并触发取消选中事件 - list.splice(i, 1); - setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, n]); - } - } - } - }, - /** - * 创建节点回调函数 - * @param {Object} setting - 配置对象,包含回调和视图设置 - */ - createNodeCallback: function (setting) { - // 检查是否有自定义的节点创建回调或添加自定义DOM的方法 - if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { - // 获取根节点数据 - var root = data.getRoot(setting); - // 当根节点的已创建节点列表不为空时循环处理 - while (root.createdNodes.length > 0) { - // 从已创建节点列表中移除并获取第一个节点 - var node = root.createdNodes.shift(); - // 调用视图中的添加自定义DOM方法 - tools.apply(setting.view.addDiyDom, [setting.treeId, node]); - // 如果存在节点创建回调,则触发该回调事件 - if (!!setting.callback.onNodeCreated) { - setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]); - } - } - } - }, - createNodes: function (setting, level, nodes, parentNode, index) { - // 如果节点为空或长度为0,则直接返回 - if (!nodes || nodes.length == 0) return; - - // 获取根节点 - var root = data.getRoot(setting), - // 判断是否打开父节点的标志 - openFlag = !parentNode || parentNode.open || !!$$(data.nodeChildren(setting, parentNode)[0], setting).get(0); - - // 初始化创建的节点数组 - root.createdNodes = []; - - // 生成节点的HTML并追加到视图中 - var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, index, true, openFlag), - parentObj, nextObj; - - // 如果没有父节点,则将生成的HTML追加到树对象中 - if (!parentNode) { - parentObj = setting.treeObj; - //setting.treeObj.append(zTreeHtml.join('')); - } else { - // 获取父节点的UL对象 - var ulObj = $$(parentNode, consts.id.UL, setting); - if (ulObj.get(0)) { - parentObj = ulObj; - //ulObj.append(zTreeHtml.join('')); - } - } - - // 如果父对象存在 - if (parentObj) { - // 如果索引大于等于0,则获取下一个兄弟节点 - if (index >= 0) { - nextObj = parentObj.children()[index]; - } - // 如果索引大于等于0且下一个兄弟节点存在,则在该节点之前插入生成的HTML - if (index >= 0 && nextObj) { - $(nextObj).before(zTreeHtml.join('')); - } else { - // 否则直接在父对象中追加生成的HTML - parentObj.append(zTreeHtml.join('')); - } - } - - view.createNodeCallback(setting); - }, - destroy: function (setting) { - // 如果 setting 为空,直接返回 - if (!setting) return; - // 初始化缓存 - data.initCache(setting); - // 初始化根节点 - data.initRoot(setting); - // 解绑树的事件 - event.unbindTree(setting); - // 解绑其他事件 - event.unbindEvent(setting); - // 清空树对象的内容 - setting.treeObj.empty(); - // 删除 settings 中对应的树设置 - delete settings[setting.treeId]; - }, - expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) { - // 获取根节点 - var root = data.getRoot(setting); - var tmpCb, _callback; - // 如果 node 为空,执行回调并返回 - if (!node) { - tools.apply(callback, []); - return; - } - // 获取子节点 - var children = data.nodeChildren(setting, node); - // 判断是否为父节点 - var isParent = data.nodeIsParent(setting, node); - // 如果根节点的 expandTriggerFlag 为真 - if (root.expandTriggerFlag) { - _callback = callback; - tmpCb = function () { - // 如果存在回调函数,则执行回调 - if (_callback) _callback(); - // 根据节点的 open 状态触发相应的事件 - if (node.open) { - setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]); - } else { - setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]); - } - }; - callback = tmpCb; - // 将临时回调函数赋值给回调变量 - root.expandTriggerFlag = false; - // 重置根节点的展开触发标志 - } - if (!node.open && isParent && ((!$$(node, consts.id.UL, setting).get(0)) || (children && children.length > 0 && !$$(children[0], setting).get(0)))) { - // 如果节点未打开且是父节点,并且没有子节点或子节点的第一个元素不存在 - view.appendParentULDom(setting, node); - // 为父节点添加子节点的DOM结构 - view.createNodeCallback(setting); - // 创建节点的回调函数 - } - if (node.open == expandFlag) { - // 如果节点的打开状态与期望的展开标志相同 - tools.apply(callback, []); - // 执行回调函数 - return; - // 结束函数执行 - } - var ulObj = $$(node, consts.id.UL, setting), - // 获取节点的UL对象 - switchObj = $$(node, consts.id.SWITCH, setting), - // 获取节点的开关对象 - icoObj = $$(node, consts.id.ICON, setting); - // 获取节点的图标对象 - - if (isParent) { - // 如果节点是父节点 - node.open = !node.open; - // 切换节点的打开状态 - if (node.iconOpen && node.iconClose) { - // 如果节点有打开和关闭的图标 - icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); - // 根据节点的状态设置图标样式 - } - - if (node.open) { - // 如果节点是打开状态,替换开关类为打开状态的样式 - view.replaceSwitchClass(node, switchObj, consts.folder.OPEN); - // 替换图标类为打开状态的样式 - view.replaceIcoClass(node, icoObj, consts.folder.OPEN); - - // 如果没有动画标志或展开速度为空,直接显示子节点 - if (animateFlag == false || setting.view.expandSpeed == "") { - ulObj.show(); - // 执行回调函数 - tools.apply(callback, []); - } else { - // 如果有子节点,使用滑动效果展开子节点 - if (children && children.length > 0) { - ulObj.slideDown(setting.view.expandSpeed, callback); - } else { - // 否则直接显示子节点 - ulObj.show(); - // 执行回调函数 - tools.apply(callback, []); - } - } - } else { - // 如果节点是关闭状态,替换开关类为关闭状态的样式 - view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE); - // 替换图标类为关闭状态的样式 - view.replaceIcoClass(node, icoObj, consts.folder.CLOSE); - - // 如果没有动画标志、展开速度为空或没有子节点,直接隐藏子节点 - if (animateFlag == false || setting.view.expandSpeed == "" || !(children && children.length > 0)) { - ulObj.hide(); - // 执行回调函数 - tools.apply(callback, []); - } else { - // 否则使用滑动效果隐藏子节点 - ulObj.slideUp(setting.view.expandSpeed, callback); - } - } - } else { - // 如果节点不存在,直接执行回调函数 - tools.apply(callback, []); - } - expandCollapseParentNode: function (setting, node, expandFlag, animateFlag, callback) { - // 如果节点不存在,直接返回 - if (!node) return; - // 如果节点没有父节点ID,则直接展开或折叠该节点 - if (!node.parentTId) { - view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); - return; - } else { - // 否则先展开或折叠当前节点 - view.expandCollapseNode(setting, node, expandFlag, animateFlag); - } - // 如果节点有父节点ID,递归展开或折叠父节点 - if (node.parentTId) { - view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback); - } - }, - /** - * 展开或折叠子节点 - * @param {Object} setting - 配置对象 - * @param {Object} node - 当前节点 - * @param {Boolean} expandFlag - 是否展开 - * @param {Boolean} animateFlag - 是否带动画 - * @param {Function} callback - 回调函数 - */ - expandCollapseSonNode: function (setting, node, expandFlag, animateFlag, callback) { - // 获取根节点 - var root = data.getRoot(setting), - // 获取子节点列表 - treeNodes = (node) ? data.nodeChildren(setting, node) : data.nodeChildren(setting, root), - // 如果是根节点,则使用传入的动画标志,否则不使用动画 - selfAnimateSign = (node) ? false : animateFlag, - // 保存当前的展开触发标志 - expandTriggerFlag = data.getRoot(setting).expandTriggerFlag; - // 暂时禁用展开触发标志 - data.getRoot(setting).expandTriggerFlag = false; - // 如果存在子节点列表,遍历并展开或折叠每个子节点 - if (treeNodes) { - for (var i = 0, l = treeNodes.length; i < l; i++) { - if (treeNodes[i]) view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign); - } - } - // 恢复原来的展开触发标志 - data.getRoot(setting).expandTriggerFlag = expandTriggerFlag; - // 最后展开或折叠当前节点 - view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); - }, - /** - * 判断节点是否被选中 - * @param {Object} setting - 配置对象 - * @param {Object} node - 当前节点 - * @returns {Boolean} - 是否被选中 - */ - isSelectedNode: function (setting, node) { - // 如果节点不存在,返回false - if (!node) { - return false; - } - // 获取当前选中的节点列表 - var list = data.getRoot(setting).curSelectedList, - i; - // 遍历选中的节点列表,检查是否存在与当前节点相同的节点 - for (i = list.length - 1; i >= 0; i--) { - if (node === list[i]) { - return true; - } - } - // 如果未找到匹配的节点,返回false - return false; - }, - makeDOMNodeIcon: function (html, setting, node) { - // 获取节点名称字符串 - var nameStr = data.nodeName(setting, node), - // 根据设置决定是否将名称作为HTML显示,否则进行转义处理 - name = setting.view.nameIsHTML ? nameStr : nameStr.replace(/&/g, '&').replace(//g, '>'); - // 生成包含图标和名称的HTML片段并推入html数组中 - html.push("", name, ""); - }, - makeDOMNodeLine: function (html, setting, node) { - // 生成节点线(用于表示树结构的连接线)的HTML片段并推入html数组中 - html.push(""); - }, - makeDOMNodeMainAfter: function (html, setting, node) { - // 在主节点的HTML片段后添加结束标签
  • - html.push(""); - }, - makeDOMNodeMainBefore: function (html, setting, node) { - // 在主节点的HTML片段前添加开始标签
  • ,并设置相关属性 - html.push("
  • "); - }, - makeDOMNodeNameAfter: function (html, setting, node) { - // 在节点名称的HTML片段后添加结束标签 - html.push(""); - }, - makeDOMNodeNameBefore: function (html, setting, node) { - // 获取节点标题、URL、字体CSS样式和节点类名 - var title = data.nodeTitle(setting, node), - url = view.makeNodeUrl(setting, node), - fontcss = view.makeNodeFontCss(setting, node), - nodeClasses = view.makeNodeClasses(setting, node), - fontStyle = []; - // 遍历字体CSS样式对象,将其转换为字符串形式并推入fontStyle数组中 - for (var f in fontcss) { - fontStyle.push(f, ":", fontcss[f], ";"); - } - html.push(" 0) ? " href='" + url + "'" : ""), " target='", view.makeNodeTarget(node), "' style='", fontStyle.join(''), - "'"); - // 如果需要显示标题并且标题存在,则添加title属性 - if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) { - html.push("title='", title.replace(/'/g, "'").replace(//g, '>'), "'"); - } - html.push(">"); - }, - makeNodeFontCss: function (setting, node) { - // 获取节点的字体样式 - var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss); - // 如果fontCss存在且不是函数,则返回fontCss,否则返回空对象 - return (fontCss && ((typeof fontCss) != "function")) ? fontCss : {}; - }, - makeNodeClasses: function (setting, node) { - // 获取节点的类名 - var classes = tools.apply(setting.view.nodeClasses, [setting.treeId, node], setting.view.nodeClasses); - // 如果classes存在且不是函数,则返回classes,否则返回默认的类名对象 - return (classes && (typeof classes !== "function")) ? classes : {add:[], remove:[]}; - }, - makeNodeIcoClass: function (setting, node) { - // 初始化图标类名数组 - var icoCss = ["ico"]; - // 如果节点没有正在加载数据 - if (!node.isAjaxing) { - // 判断节点是否是父节点 - var isParent = data.nodeIsParent(setting, node); - // 根据节点是否有iconSkin设置前缀 - icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0]; - if (isParent) { - // 如果是父节点,根据节点是否展开添加相应的图标类名 - icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); - } else { - // 如果不是父节点,添加文档图标类名 - icoCss.push(consts.folder.DOCU); - } - } - // 返回拼接后的按钮类名和图标类名 - return consts.className.BUTTON + " " + icoCss.join('_'); - }, - makeNodeIcoStyle: function (setting, node) { - // 初始化图标样式数组 - var icoStyle = []; - // 如果节点没有进行Ajax请求 - if (!node.isAjaxing) { - // 判断节点是否是父节点 - var isParent = data.nodeIsParent(setting, node); - // 根据节点状态选择相应的图标 - var icon = (isParent && node.iconOpen && node.iconClose) ? (node.open ? node.iconOpen : node.iconClose) : node[setting.data.key.icon]; - // 如果存在图标,则添加背景图片样式 - if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;"); - // 如果视图设置中不显示图标或应用showIcon函数返回false,则隐藏图标 - if (setting.view.showIcon == false || !tools.apply(setting.view.showIcon, [setting.treeId, node], true)) { - icoStyle.push("display:none;"); - } - } - // 返回拼接后的图标样式字符串 - return icoStyle.join(''); - }, - makeNodeLineClass: function (setting, node) { - // 初始化线条样式数组 - var lineClass = []; - // 如果视图设置中显示线条 - if (setting.view.showLine) { - // 根据节点层级和位置添加相应的线条样式 - // 检查节点是否为根节点且是第一个和最后一个节点 - if (node.level == 0 && node.isFirstNode && node.isLastNode) { - // 将根节点的样式类添加到lineClass数组中 - lineClass.push(consts.line.ROOT); - } else if (node.level == 0 && node.isFirstNode) { - // 检查节点是否为根节点且是第一个节点 - // 将根节点的第一个样式类添加到lineClass数组中 - lineClass.push(consts.line.ROOTS); - } else if (node.isLastNode) { - // 检查节点是否是最后一个节点 - // 将底部节点的样式类添加到lineClass数组中 - lineClass.push(consts.line.BOTTOM); - } else { - // 默认情况下,将中心节点的样式类添加到lineClass数组中 - lineClass.push(consts.line.CENTER); - } - } else { - // 如果不显示线条,则添加无线条样式 - lineClass.push(consts.line.NOLINE); - } - // 根据节点是否为父节点添加文件夹样式 - if (data.nodeIsParent(setting, node)) { - lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); - } else { - lineClass.push(consts.folder.DOCU); - } - // 返回拼接后的线条样式字符串,并调用makeNodeLineClassEx方法进一步处理 - return view.makeNodeLineClassEx(node) + lineClass.join('_'); - }, - makeNodeLineClassEx: function (node) { - // 返回节点的按钮、层级和开关样式字符串 - return consts.className.BUTTON + " " + consts.className.LEVEL + node.level + " " + consts.className.SWITCH + " "; - }, - makeNodeTarget: function (node) { - // 返回节点的目标属性,如果不存在则默认为"_blank" - return (node.target || "_blank"); - }, - makeNodeUrl: function (setting, node) { - // 获取URL键值 - var urlKey = setting.data.key.url; - // 返回节点的URL,如果不存在则返回null - return node[urlKey] ? node[urlKey] : null; - }, - makeUlHtml: function (setting, node, html, content) { - // 生成UL元素的HTML代码,并根据节点状态设置显示或隐藏 - html.push("
      "); - // 插入内容到UL元素中 - html.push(content); - // 关闭UL标签 - html.push("
    "); - }, - makeUlLineClass: function (setting, node) { - // 如果视图显示线条且节点不是最后一个节点,则返回线条类名,否则返回空字符串 - return ((setting.view.showLine && !node.isLastNode) ? consts.line.LINE : ""); - }, - removeChildNodes: function (setting, node) { - // 如果节点不存在,直接返回 - if (!node) return; - // 获取节点的子节点列表 - var nodes = data.nodeChildren(setting, node); - // 如果子节点列表不存在,直接返回 - if (!nodes) return; - - // 遍历所有子节点 - for (var i = 0, l = nodes.length; i < l; i++) { - // 移除每个子节点的缓存 - data.removeNodeCache(setting, nodes[i]); - } - data.removeSelectedNode(setting); // 移除选中的节点 - delete node[setting.data.key.children]; // 删除节点的子节点属性 - - if (!setting.data.keep.parent) { // 如果设置中不保留父节点 - data.nodeIsParent(setting, node, false); // 将当前节点设置为非父节点 - node.open = false; // 关闭当前节点 - var tmp_switchObj = $$(node, consts.id.SWITCH, setting), // 获取当前节点的开关对象 - tmp_icoObj = $$(node, consts.id.ICON, setting); // 获取当前节点的图标对象 - view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU); // 替换开关对象的类为文档文件夹样式 - view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU); // 替换图标对象的类为文档文件夹样式 - $$(node, consts.id.UL, setting).remove(); // 移除当前节点的子节点列表 - } else { - $$(node, consts.id.UL, setting).empty(); // 如果保留父节点,则清空子节点列表 - } - scrollIntoView: function (setting, dom) { - // 如果dom不存在,直接返回 - if (!dom) { - return; - } - // 支持IE 7 / 8 - if (typeof Element === 'undefined' || typeof HTMLElement === 'undefined') { - // 获取容器的边界矩形 - var contRect = setting.treeObj.get(0).getBoundingClientRect(), - // 获取目标元素的边界矩形 - findMeRect = dom.getBoundingClientRect(); - // 检查目标元素是否在容器视图之外 - if (findMeRect.top < contRect.top || findMeRect.bottom > contRect.bottom - || findMeRect.right > contRect.right || findMeRect.left < contRect.left) { - // 将目标元素滚动到视图中 - dom.scrollIntoView(); - } - return; - } - // CC-BY jocki84@googlemail.com, https://gist.github.com/jocki84/6ffafd003387179a988e - if (!Element.prototype.scrollIntoViewIfNeeded) { - // 如果浏览器不支持 scrollIntoViewIfNeeded 方法,则定义该方法 - Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) { - "use strict"; - - // 创建一个表示范围的对象,包含起始位置和长度 - function makeRange(start, length) { - return {"start": start, "length": length, "end": start + length}; - } - - // 根据是否需要居中来调整范围的覆盖方式 - function coverRange(inner, outer) { - if ( - false === centerIfNeeded || - (outer.start < inner.end && inner.start < outer.end) - ) { - // 如果不居中或内外范围有重叠,返回最大值或最小值 - return Math.max( - inner.end - outer.length, - Math.min(outer.start, inner.start) - ); - } - // 如果需要居中,返回中间值 - return (inner.start + inner.end - outer.length) / 2; - } - - // 创建一个表示点的对象,包含 x 和 y 坐标以及平移方法 - function makePoint(x, y) { - return { - "x": x, - "y": y, - "translate": function translate(dX, dY) { - // 平移点的位置 - return makePoint(x + dX, y + dY); - } - }; - } - - /** - * 计算元素在页面中的绝对位置。 - * @param {HTMLElement} elem - 需要计算位置的元素。 - * @param {Point} pt - 初始点,用于累加偏移量。 - * @returns {Point} - 返回元素的绝对位置。 - */ - function absolute(elem, pt) { - // 当元素存在时循环执行 - while (elem) { - // 将当前元素的偏移量累加到初始点上 - pt = pt.translate(elem.offsetLeft, elem.offsetTop); - // 获取当前元素的父级偏移容器 - elem = elem.offsetParent; - } - // 返回计算后的绝对位置 - return pt; - } - - var target = absolute(this, makePoint(0, 0)), // 计算目标元素的绝对位置 - extent = makePoint(this.offsetWidth, this.offsetHeight), // 获取目标元素的宽度和高度 - elem = this.parentNode, // 获取目标元素的父节点 - origin; // 定义变量origin用于存储当前元素的绝对位置 - - while (elem instanceof HTMLElement) { // 当elem是HTML元素时循环执行 - // Apply desired scroll amount. - origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop)); // 计算当前元素的绝对位置 - elem.scrollLeft = coverRange( // 设置水平滚动条的位置,使其覆盖目标范围 - makeRange(target.x - origin.x, extent.x), // 计算目标范围的左边界 - makeRange(elem.scrollLeft, elem.clientWidth) // 计算当前可视区域的范围 - ); - elem.scrollTop = coverRange( // 设置垂直滚动条的位置,使其覆盖目标范围 - makeRange(target.y - origin.y, extent.y), // 计算目标范围的上边界 - makeRange(elem.scrollTop, elem.clientHeight) // 计算当前可视区域的范围 - ); - - // Determine actual scroll amount by reading back scroll properties. - target = target.translate(-elem.scrollLeft, -elem.scrollTop); - // 将目标元素的位置平移,以考虑滚动条的偏移量 - - elem = elem.parentNode; - // 将当前元素更新为其父节点,以便继续向上遍历DOM树 - - dom.scrollIntoViewIfNeeded(); - // 如果需要,将DOM元素滚动到视图中 - - setFirstNode: function (setting, parentNode) { - // 定义一个方法,用于设置父节点的第一个子节点 - - var children = data.nodeChildren(setting, parentNode); - // 获取父节点的所有子节点 - - if (children.length > 0) { - // 如果父节点有子节点 - - children[0].isFirstNode = true; - // 将第一个子节点标记为第一个节点 - } - }, - setLastNode: function (setting, parentNode) { - // 获取父节点的所有子节点 - var children = data.nodeChildren(setting, parentNode); - // 如果子节点数组不为空,则将最后一个子节点标记为isLastNode - if (children.length > 0) { - children[children.length - 1].isLastNode = true; - } - }, - removeNode: function (setting, node) { - // 获取根节点 - var root = data.getRoot(setting), - // 获取父节点,如果当前节点有parentTId属性,则获取其父节点,否则获取根节点 - parentNode = (node.parentTId) ? node.getParentNode() : root; - - // 将当前节点的isFirstNode和isLastNode属性设为false - node.isFirstNode = false; - node.isLastNode = false; - // 定义一个方法,返回null,表示没有前一个节点 - node.getPreNode = function () { - return null; - }; - // 定义一个方法,返回null,表示没有下一个节点 - node.getNextNode = function () { - return null; - }; - - // 检查节点缓存是否存在,如果不存在则直接返回 - if (!data.getNodeCache(setting, node.tId)) { - return; - } - - // 从DOM中移除节点 - $$(node, setting).remove(); - // 从节点缓存中移除该节点 - data.removeNodeCache(setting, node); - // 从选中的节点列表中移除该节点 - data.removeSelectedNode(setting, node); - - // 获取父节点的所有子节点 - var children = data.nodeChildren(setting, parentNode); - // 遍历所有子节点 - for (var i = 0, l = children.length; i < l; i++) { - // 如果找到与要删除节点相同的节点 - if (children[i].tId == node.tId) { - // 从子节点数组中移除该节点 - children.splice(i, 1); - // 退出循环 - break; - } - } - view.setFirstNode(setting, parentNode); // 设置第一个节点 - view.setLastNode(setting, parentNode); // 设置最后一个节点 - - var tmp_ulObj, tmp_switchObj, tmp_icoObj, - childLength = children.length; // 获取子节点的长度 - - // 修复旧父节点的子节点信息 - if (!setting.data.keep.parent && childLength == 0) { - // 如果旧父节点没有子节点 - data.nodeIsParent(setting, parentNode, false); // 更新数据,标记该节点不是父节点 - parentNode.open = false; // 关闭父节点 - delete parentNode[setting.data.key.children]; // 删除父节点的子节点属性 - tmp_ulObj = $$(parentNode, consts.id.UL, setting); // 获取父节点的UL对象 - tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting); // 获取父节点的SWITCH对象 - tmp_icoObj = $$(parentNode, consts.id.ICON, setting); // 获取父节点的ICON对象 - view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU); // 替换SWITCH对象的类为文档文件夹样式 - view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU); // 替换ICON对象的类为文档文件夹样式 - tmp_ulObj.css("display", "none"); // 隐藏UL对象 - } - else if (setting.view.showLine && childLength > 0) { - // 如果设置中显示线条且子节点数量大于0 - var newLast = children[childLength - 1]; - // 获取最后一个子节点 - tmp_ulObj = $$(newLast, consts.id.UL, setting); - // 获取最后一个子节点的UL对象 - tmp_switchObj = $$(newLast, consts.id.SWITCH, setting); - // 获取最后一个子节点的SWITCH对象 - tmp_icoObj = $$(newLast, consts.id.ICON, setting); - // 获取最后一个子节点的ICON对象 - if (parentNode == root) { - // 如果父节点是根节点 - if (children.length == 1) { - // 如果只有一个子节点,即该节点原本是根节点 - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT); - // 替换为根节点样式 - } else { - var tmp_first_switchObj = $$(children[0], consts.id.SWITCH, setting); - // 获取第一个子节点的SWITCH对象 - view.replaceSwitchClass(children[0], tmp_first_switchObj, consts.line.ROOTS); - // 替换第一个子节点为多根节点样式 - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); - // 替换最后一个子节点为底部节点样式 - } - } else { - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); - // 如果不是根节点,则替换最后一个子节点为底部节点样式 - } - tmp_ulObj.removeClass(consts.line.LINE); - // 移除UL对象的线条样式 - } - }, - /** - * 替换节点的图标类名 - * @param {Object} node - DOM节点对象 - * @param {Object} obj - 包含class属性的对象 - * @param {string} newName - 新的类名 - */ - replaceIcoClass: function (node, obj, newName) { - // 如果obj为空或节点正在Ajax请求中,则直接返回 - if (!obj || node.isAjaxing) return; - - // 获取对象的class属性值 - var tmpName = obj.attr("class"); - - // 如果class属性值为undefined,则直接返回 - if (tmpName == undefined) return; - - // 将class属性值按"_"分割成数组 - var tmpList = tmpName.split("_"); - - // 根据newName的值进行不同的处理 - switch (newName) { - case consts.folder.OPEN: - case consts.folder.CLOSE: - case consts.folder.DOCU: - // 将数组最后一个元素替换为newName - tmpList[tmpList.length - 1] = newName; - break; - } - - // 将修改后的数组重新拼接成字符串并设置回对象的class属性 - obj.attr("class", tmpList.join("_")); - }, - /** - * 替换节点的类名 - * @param {Object} node - 需要操作的节点对象 - * @param {Object} obj - 包含类名属性的对象 - * @param {string} newName - 新的类名 - */ - replaceSwitchClass: function (node, obj, newName) { - // 如果obj为空,直接返回 - if (!obj) return; - // 获取当前对象的class属性值 - var tmpName = obj.attr("class"); - // 如果class属性值为undefined,直接返回 - if (tmpName == undefined) return; - // 将class属性值按"_"分割成数组 - var tmpList = tmpName.split("_"); - // 根据newName的值进行不同的处理 - switch (newName) { - case consts.line.ROOT: - case consts.line.ROOTS: - case consts.line.CENTER: - case consts.line.BOTTOM: - case consts.line.NOLINE: - // 更新数组的第一个元素为新的类名 - tmpList[0] = view.makeNodeLineClassEx(node) + newName; - break; - case consts.folder.OPEN: - case consts.folder.CLOSE: - case consts.folder.DOCU: - // 更新数组的第二个元素为新的类名 - tmpList[1] = newName; - break; - } - // 将更新后的数组重新拼接成字符串并设置回class属性 - obj.attr("class", tmpList.join("_")); - // 如果newName不是DOCU,移除disabled属性;否则添加disabled属性 - if (newName !== consts.folder.DOCU) { - obj.removeAttr("disabled"); - } else { - obj.attr("disabled", "disabled"); - } - }, - selectNode: function (setting, node, addFlag) { - // 如果没有添加标志,则取消先前选择的节点 - if (!addFlag) { - view.cancelPreSelectedNode(setting, null, node); - } - // 为当前节点添加选中样式 - $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED); - // 将当前节点添加到已选节点列表中 - data.addSelectedNode(setting, node); - // 触发选中事件 - setting.treeObj.trigger(consts.event.SELECTED, [setting.treeId, node]); - }, - setNodeFontCss: function (setting, treeNode) { - // 获取节点对应的DOM对象 - var aObj = $$(treeNode, consts.id.A, setting), - // 生成节点字体样式 - fontCss = view.makeNodeFontCss(setting, treeNode); - // 如果存在字体样式,则应用到节点上 - if (fontCss) { - aObj.css(fontCss); - } - }, - /** - * 设置节点的CSS类 - * @param {Object} setting - 配置对象 - * @param {Object} treeNode - 树节点对象 - */ - setNodeClasses: function (setting, treeNode) { - // 获取树节点对应的
    元素对象 - var aObj = $$(treeNode, consts.id.A, setting), - // 生成需要添加和移除的CSS类名集合 - classes = view.makeNodeClasses(setting, treeNode); - - // 如果需要添加的CSS类名存在且不为空,则添加到元素中 - if ('add' in classes && classes.add.length) { - aObj.addClass(classes.add.join(' ')); - } - - // 如果需要移除的CSS类名存在且不为空,则从元素中移除 - if ('remove' in classes && classes.remove.length) { - aObj.removeClass(classes.remove.join(' ')); - } - }, - setNodeLineIcos: function (setting, node) { - // 如果节点不存在,直接返回 - if (!node) return; - - // 获取节点的开关对象、UL对象和图标对象 - var switchObj = $$(node, consts.id.SWITCH, setting), - ulObj = $$(node, consts.id.UL, setting), - icoObj = $$(node, consts.id.ICON, setting), - - // 生成UL对象的行样式类名 - ulLine = view.makeUlLineClass(setting, node); - - // 如果行样式类名为空,移除UL对象的行样式类名 - if (ulLine.length == 0) { - ulObj.removeClass(consts.line.LINE); - } else { - // 否则,添加行样式类名到UL对象 - ulObj.addClass(ulLine); - } - - // 设置开关对象的类名 - switchObj.attr("class", view.makeNodeLineClass(setting, node)); - - // 如果节点是父节点,移除开关对象的禁用属性;否则,设置开关对象为禁用状态 - if (data.nodeIsParent(setting, node)) { - switchObj.removeAttr("disabled"); - } else { - switchObj.attr("disabled", "disabled"); - } - - // 移除图标对象的内联样式 - icoObj.removeAttr("style"); - - // 设置图标对象的内联样式和类名 - icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); - icoObj.attr("class", view.makeNodeIcoClass(setting, node)); - }, - setNodeName: function (setting, node) { - // 获取节点的标题 - var title = data.nodeTitle(setting, node), - // 获取节点对应的SPAN元素对象 - nObj = $$(node, consts.id.SPAN, setting); - // 清空SPAN元素的内容 - nObj.empty(); - // 如果视图名称是HTML格式 - if (setting.view.nameIsHTML) { - // 将节点的名称作为HTML内容设置到SPAN元素中 - nObj.html(data.nodeName(setting, node)); - } else { - // 将节点的名称作为文本内容设置到SPAN元素中 - nObj.text(data.nodeName(setting, node)); - } - // 如果需要显示标题 - if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) { - // 获取节点对应的A元素对象 - var aObj = $$(node, consts.id.A, setting); - // 设置A元素的title属性为节点的标题,如果标题为空则设置为空字符串 - aObj.attr("title", !title ? "" : title); - } - }, - setNodeTarget: function (setting, node) { - // 获取节点对应的元素对象 - var aObj = $$(node, consts.id.A, setting); - // 设置元素的target属性为生成的节点目标值 - aObj.attr("target", view.makeNodeTarget(node)); - }, - setNodeUrl: function (setting, node) { - // 获取节点对应的元素对象 - var aObj = $$(node, consts.id.A, setting), - // 生成节点的URL - url = view.makeNodeUrl(setting, node); - // 如果URL为空或长度为0,则移除元素的href属性 - if (url == null || url.length == 0) { - aObj.removeAttr("href"); - } else { - // 否则,设置元素的href属性为生成的URL - aObj.attr("href", url); - } - }, - switchNode: function (setting, node) { - // 如果节点已经打开,或者节点不能异步加载,则切换节点的展开/折叠状态 - if (node.open || !tools.canAsync(setting, node)) { - // 调用视图方法切换节点的展开/折叠状态 - view.expandCollapseNode(setting, node, !node.open); - } else if (setting.async.enable) { - // 如果启用了异步加载,并且节点不能异步加载,则切换节点的展开/折叠状态 - if (!view.asyncNode(setting, node)) { - // 调用视图方法切换节点的展开/折叠状态 - view.expandCollapseNode(setting, node, !node.open); - return; // 结束函数执行 - } - } else if (node) { - // 如果节点存在,则切换节点的展开/折叠状态 - view.expandCollapseNode(setting, node, !node.open); - } - } - }; - // zTree defind - $.fn.zTree = { - // 常量对象,包含一些全局的常量值 - consts: _consts, - // 内部工具对象,包含各种工具方法 - _z: { - tools: tools, - // 视图相关的方法 - view: view, - // 事件相关的方法 - event: event, - // 数据相关的方法 - data: data - }, - /** - * 获取指定树ID的zTree对象 - * @param {string} treeId - 树的ID - * @returns {Object|null} 返回对应的zTree对象,如果不存在则返回null - */ - getZTreeObj: function (treeId) { - // 从data中获取zTree工具对象 - var o = data.getZTreeTools(treeId); - // 如果存在则返回该对象,否则返回null - return o ? o : null; - }, - /** - * 销毁指定的zTree实例或所有zTree实例 - * @param {string} [treeId] - 可选参数,树的ID。如果提供则销毁指定ID的树,否则销毁所有树 - */ - destroy: function (treeId) { - // 如果提供了treeId且其长度大于0 - if (!!treeId && treeId.length > 0) { - // 销毁指定ID的树 - view.destroy(data.getSetting(treeId)); - } else { - // 遍历所有设置并销毁每一个树 - for (var s in settings) { - view.destroy(settings[s]); - } - } - }, - init: function (obj, zSetting, zNodes) { - // 克隆默认设置对象 - var setting = tools.clone(_setting); - // 深度合并用户自定义设置到默认设置中 - $.extend(true, setting, zSetting); - // 设置树的ID为传入对象的ID - setting.treeId = obj.attr("id"); - // 将传入的对象赋值给树对象 - setting.treeObj = obj; - // 清空树对象的内容 - setting.treeObj.empty(); - // 将设置存储在全局settings对象中,以树ID为键 - settings[setting.treeId] = setting; - // 针对一些旧浏览器(例如ie6),如果不支持maxHeight样式属性,则禁用展开速度 - if (typeof document.body.style.maxHeight === "undefined") { - setting.view.expandSpeed = ""; - } - // 初始化根节点数据 - data.initRoot(setting); - // 获取根节点数据 - var root = data.getRoot(setting); - // 如果zNodes存在,则克隆并转换为数组格式;否则设置为空数组 - zNodes = zNodes ? tools.clone(tools.isArray(zNodes) ? zNodes : [zNodes]) : []; - // 如果启用了简单数据模式,则转换节点数据格式后添加到根节点 - if (setting.data.simpleData.enable) { - data.nodeChildren(setting, root, data.transformTozTreeFormat(setting, zNodes)); - } else { - // 否则直接添加节点数据到根节点 - data.nodeChildren(setting, root, zNodes); - } - - // 初始化缓存,传入设置参数 - data.initCache(setting); - - // 解绑树形结构的事件,传入设置参数 - event.unbindTree(setting); - - // 绑定树形结构的事件,传入设置参数 - event.bindTree(setting); - - // 解绑其他事件,传入设置参数 - event.unbindEvent(setting); - - // 绑定其他事件,传入设置参数 - event.bindEvent(setting); - var zTreeTools = { - // 设置对象 - setting: setting, - /** - * 添加节点函数 - * @param {Object} parentNode - 父节点对象 - * @param {number|string} index - 插入位置的索引或新节点数组 - * @param {Array|Object} newNodes - 要添加的新节点,可以是单个节点对象或节点数组 - * @param {boolean} isSilent - 是否静默添加(不触发事件) - * @returns {null|undefined} 如果无法添加节点则返回null - */ - addNodes: function (parentNode, index, newNodes, isSilent) { - // 如果未提供父节点,则默认为null - if (!parentNode) parentNode = null; - // 检查父节点是否是父节点类型 - var isParent = data.nodeIsParent(setting, parentNode); - // 如果父节点不是父节点且配置中要求保持叶子节点,则返回null - if (parentNode && !isParent && setting.data.keep.leaf) return null; - - // 将index转换为整数 - var i = parseInt(index, 10); - // 如果index不是数字,则调整参数 - if (isNaN(i)) { - isSilent = !!newNodes; // 判断newNodes是否存在,存在则isSilent为true - newNodes = index; // 将index赋值给newNodes - index = -1; // 重置index为-1 - } else { - index = i; // 否则使用转换后的整数index - } - // 如果newNodes不存在,则返回null - if (!newNodes) return null; - - // 克隆新的节点数组,确保其为数组形式 - var xNewNodes = tools.clone(tools.isArray(newNodes) ? newNodes : [newNodes]); - - // 定义添加节点的回调函数 - function addCallback() { - // 调用视图层的addNodes方法实际添加节点 - view.addNodes(setting, parentNode, index, xNewNodes, (isSilent == true)); - } - - if (tools.canAsync(setting, parentNode)) { - // 检查是否可以异步加载节点,如果可以则调用view.asyncNode方法进行异步加载 - view.asyncNode(setting, parentNode, isSilent, addCallback); - } else { - // 如果不支持异步加载,直接调用回调函数 - addCallback(); - } - // 返回新添加的节点 - return xNewNodes; - }, - cancelSelectedNode: function (node) { - // 取消选中的节点 - view.cancelPreSelectedNode(setting, node); - }, - destroy: function () { - // 销毁视图 - view.destroy(setting); - }, - expandAll: function (expandFlag) { - // 确保expandFlag为布尔值 - expandFlag = !!expandFlag; - // 展开或折叠所有子节点 - view.expandCollapseSonNode(setting, null, expandFlag, true); - // 返回最终的展开标志 - return expandFlag; - }, - expandNode: function (node, expandFlag, sonSign, focus, callbackFlag) { - // 如果节点不存在或者不是父节点,返回null - if (!node || !data.nodeIsParent(setting, node)) return null; - // 如果expandFlag既不是true也不是false,则取反当前节点的open状态 - if (expandFlag !== true && expandFlag !== false) { - expandFlag = !node.open; - } - // 确保callbackFlag为布尔值 - callbackFlag = !!callbackFlag; - - // 检查是否需要在展开或折叠节点之前执行回调函数 - if (callbackFlag && expandFlag && (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false)) { - // 如果回调函数返回false,则不进行展开操作,直接返回null - return null; - } else if (callbackFlag && !expandFlag && (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false)) { - // 如果回调函数返回false,则不进行折叠操作,直接返回null - return null; - } - - // 如果需要展开节点且该节点有父节点 - if (expandFlag && node.parentTId) { - // 递归展开父节点 - view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false); - } - - // 如果节点的展开状态与目标状态相同且没有子节点标志 - if (expandFlag === node.open && !sonSign) { - // 不需要改变节点状态,直接返回null - return null; - } - - // 设置根节点的展开触发标志为回调标志 - data.getRoot(setting).expandTriggerFlag = callbackFlag; - - // 如果当前节点不能异步加载并且有子节点 - if (!tools.canAsync(setting, node) && sonSign) { - // 展开或折叠子节点,并显示节点焦点 - view.expandCollapseSonNode(setting, node, expandFlag, true, showNodeFocus); - } else { - // 否则,根据展开标志设置节点的打开状态 - node.open = !expandFlag; - // 切换节点的状态 - view.switchNode(this.setting, node); - // 显示节点焦点 - showNodeFocus(); - } - - // 返回展开标志 - return expandFlag; - - function showNodeFocus() { - // 获取节点对象 - var a = $$(node, setting).get(0); - // 如果节点存在且焦点不为false,则将视图滚动到该节点位置 - if (a && focus !== false) { - view.scrollIntoView(setting, a); - } - } - }, - getNodes: function () { - // 返回所有节点数据 - return data.getNodes(setting); - }, - getNodeByParam: function (key, value, parentNode) { - // 如果键不存在,返回null - if (!key) return null; - // 根据参数获取节点,如果parentNode存在,则在子节点中查找,否则在所有节点中查找 - return data.getNodeByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodeByTId: function (tId) { - // 根据节点ID获取缓存中的节点对象 - return data.getNodeCache(setting, tId); - }, - getNodesByParam: function (key, value, parentNode) { - // 如果键不存在,返回null - if (!key) return null; - // 根据参数获取节点数组,如果parentNode存在,则在子节点中查找,否则在所有节点中查找 - return data.getNodesByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodesByParamFuzzy: function (key, value, parentNode) { - // 如果键不存在,返回null - if (!key) return null; - // 根据模糊参数获取节点数组,如果parentNode存在,则在子节点中查找,否则在所有节点中查找 - return data.getNodesByParamFuzzy(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodesByFilter: function (filter, isSingle, parentNode, invokeParam) { - // 将isSingle转换为布尔值 - isSingle = !!isSingle; - // 如果过滤器不存在或不是函数,返回null或空数组 - if (!filter || (typeof filter != "function")) return (isSingle ? null : []); - // 根据过滤器获取节点数组,如果parentNode存在,则在子节点中查找,否则在所有节点中查找 - return data.getNodesByFilter(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), filter, isSingle, invokeParam); - }, - getNodeIndex: function (node) { - // 如果节点为空,返回null - if (!node) return null; - // 获取父节点,如果节点有parentTId属性则调用getParentNode方法,否则获取根节点 - var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); - // 获取父节点的子节点列表 - var children = data.nodeChildren(setting, parentNode); - // 遍历子节点列表,找到与目标节点匹配的索引并返回 - for (var i = 0, l = children.length; i < l; i++) { - if (children[i] == node) return i; - } - // 如果未找到匹配的节点,返回-1 - return -1; - }, - getSelectedNodes: function () { - // 初始化一个空数组用于存储选中的节点 - var r = [], list = data.getRoot(setting).curSelectedList; - // 遍历当前选中的节点列表,将每个节点添加到结果数组中 - for (var i = 0, l = list.length; i < l; i++) { - r.push(list[i]); - } - // 返回包含所有选中节点的数组 - return r; - }, - isSelectedNode: function (node) { - // 判断指定节点是否被选中,返回布尔值 - return data.isSelectedNode(setting, node); - }, - reAsyncChildNodesPromise: function (parentNode, reloadType, isSilent) { - // 创建一个新的Promise对象 - var promise = new Promise(function (resolve, reject) { - try { - // 异步重新加载子节点,并在完成后解析Promise - zTreeTools.reAsyncChildNodes(parentNode, reloadType, isSilent, function () { - resolve(parentNode); - }); - } catch (e) { - // 如果发生错误,拒绝Promise并传递错误信息 - reject(e); - } - }); - // 返回Promise对象 - return promise; - }, - /** - * 重新加载异步子节点 - * @param {Object} parentNode - 父节点对象 - * @param {string} reloadType - 重载类型,可以是 "refresh" - * @param {boolean} isSilent - 是否静默加载 - * @param {function} callback - 回调函数 - */ - reAsyncChildNodes: function (parentNode, reloadType, isSilent, callback) { - // 如果异步加载未启用,则直接返回 - if (!this.setting.async.enable) return; - - // 判断是否是根节点 - var isRoot = !parentNode; - - // 如果是根节点,获取根节点数据 - if (isRoot) { - parentNode = data.getRoot(setting); - } - - // 如果重载类型是 "refresh" - if (reloadType == "refresh") { - // 获取当前父节点的所有子节点 - var children = data.nodeChildren(setting, parentNode); - - // 遍历所有子节点并移除缓存 - for (var i = 0, l = children ? children.length : 0; i < l; i++) { - data.removeNodeCache(setting, children[i]); - } - - // 移除选中的节点 - data.removeSelectedNode(setting); - - // 清空父节点的子节点列表 - data.nodeChildren(setting, parentNode, []); - - // 如果是根节点,清空树对象 - if (isRoot) { - this.setting.treeObj.empty(); - } else { - // 否则清空父节点对应的UL元素 - var ulObj = $$(parentNode, consts.id.UL, setting); - ulObj.empty(); - } - } - - // 异步加载节点 - view.asyncNode(this.setting, isRoot ? null : parentNode, !!isSilent, callback); - }, - refresh: function () { - // 清空树对象 - this.setting.treeObj.empty(); - - // 获取根节点 - var root = data.getRoot(setting), - // 获取根节点的子节点 - nodes = data.nodeChildren(setting, root); - - // 初始化根节点 - data.initRoot(setting); - - // 将子节点重新添加到根节点 - data.nodeChildren(setting, root, nodes); - - // 初始化缓存 - data.initCache(setting); - - // 创建节点视图,参数依次为:设置、层级、子节点数组、父节点、父节点ID - view.createNodes(setting, 0, data.nodeChildren(setting, root), null, -1); - }, - removeChildNodes: function (node) { - // 如果节点为空,返回null - if (!node) return null; - // 获取指定节点的子节点 - var nodes = data.nodeChildren(setting, node); - // 从视图中移除这些子节点 - view.removeChildNodes(setting, node); - // 如果有子节点则返回它们,否则返回null - return nodes ? nodes : null; - }, - removeNode: function (node, callbackFlag) { - // 如果节点为空,直接返回 - if (!node) return; - // 确保callbackFlag是布尔值 - callbackFlag = !!callbackFlag; - // 如果callbackFlag为true且beforeRemove回调函数返回false,则不继续执行 - if (callbackFlag && tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return; - // 从视图中移除该节点 - view.removeNode(setting, node); - // 如果callbackFlag为true,触发REMOVE事件 - if (callbackFlag) { - this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); - } - }, - selectNode: function (node, addFlag, isSilent) { - // 如果节点为空,直接返回 - if (!node) return; - - // 检查用户是否有权限进行操作 - if (tools.uCanDo(setting)) { - // 如果允许多选并且addFlag为true,则保持addFlag为true - addFlag = setting.view.selectedMulti && addFlag; - - // 如果节点有父节点 - if (node.parentTId) { - // 展开父节点并聚焦到该节点 - view.expandCollapseParentNode(setting, node.getParentNode(), true, false, showNodeFocus); - } else if (!isSilent) { - // 如果节点没有父节点且不静默处理 - try { - // 尝试让节点获取焦点并失去焦点 - $$(node, setting).focus().blur(); - } catch (e) { - // 捕获异常但不做任何处理 - } - } - // 选择节点,根据addFlag决定是否添加选中状态 - view.selectNode(setting, node, addFlag); - } - - function showNodeFocus() { - // 如果当前处于静默模式,则直接返回,不执行后续操作 - if (isSilent) { - return; - } - // 获取指定节点的第一个元素 - var a = $$(node, setting).get(0); - // 将视图滚动到指定节点的位置 - view.scrollIntoView(setting, a); - } - - /** - * 将简单节点数组转换为zTree节点格式 - * @param {Array} simpleNodes - 简单节点数组 - * @returns {Array} zTree节点格式的数组 - */ - transformTozTreeNodes: function (simpleNodes) { - return data.transformTozTreeFormat(setting, simpleNodes); - }, - - /** - * 将节点数组转换为普通数组格式 - * @param {Array} nodes - 节点数组 - * @returns {Array} 普通数组格式的数组 - */ - transformToArray: function (nodes) { - return data.transformToArrayFormat(setting, nodes); - }, - updateNode: function (node, checkTypeFlag) { - // 如果节点不存在,直接返回 - if (!node) return; - - // 获取节点对象 - var nObj = $$(node, setting); - - // 如果节点对象存在且用户有权限进行操作 - if (nObj.get(0) && tools.uCanDo(setting)) { - // 设置节点名称 - view.setNodeName(setting, node); - - // 设置节点目标 - view.setNodeTarget(setting, node); - - // 设置节点URL - view.setNodeUrl(setting, node); - - // 设置节点图标 - view.setNodeLineIcos(setting, node); - - // 设置节点字体样式 - view.setNodeFontCss(setting, node); - - // 设置节点类名 - view.setNodeClasses(setting, node); - } - } - root.treeTools = zTreeTools; // 将zTreeTools对象赋值给根节点的treeTools属性 - data.setZTreeTools(setting, zTreeTools); // 设置zTree工具到数据对象中 - var children = data.nodeChildren(setting, root); // 获取根节点的子节点 - if (children && children.length > 0) { // 如果存在子节点且子节点数量大于0 - view.createNodes(setting, 0, children, null, -1); // 创建子节点视图 - } else if (setting.async.enable && setting.async.url && setting.async.url !== '') { // 如果启用了异步加载并且URL不为空 - view.asyncNode(setting); // 异步加载节点 - } - return zTreeTools; // 返回zTree工具对象 - - var zt = $.fn.zTree, // 获取jQuery的zTree插件 - $$ = tools.$, // 从tools对象中获取$符号,通常用于简化代码书写 - consts = zt.consts; // 获取zTree插件中的常量定义 - })(jQuery); // 立即执行函数,传入jQuery对象作为参数 -/* - * JQuery zTree excheck - * v3.5.46 - * http://treejs.cn/ - * - * Copyright (c) 2010 Hunter.z - * - * Licensed same as jquery - MIT License - * http://www.opensource.org/licenses/mit-license.php - * - * Date: 2020-11-21 - */ - -(function ($) { - // 定义excheck的默认常量 - var _consts = { - event: { - // 触发检查事件的名称 - CHECK: "ztree_check" - }, - id: { - // 检查框的ID前缀 - CHECK: "_check" - }, - checkbox: { - // 复选框样式类型 - STYLE: "checkbox", - // 默认复选框类名 - DEFAULT: "chk", - // 禁用状态的复选框类名 - DISABLED: "disable", - // 未选中状态的复选框类名 - FALSE: "false", - // 选中状态的复选框类名 - TRUE: "true", - // 完全选中状态的复选框类名 - FULL: "full", - // 部分选中状态的复选框类名 - PART: "part", - // 焦点状态的复选框类名 - FOCUS: "focus" - }, - radio: { - // 单选按钮样式类型 - STYLE: "radio", - // 所有节点都参与选择的类型 - TYPE_ALL: "all", - // 同级别节点参与选择的类型 - TYPE_LEVEL: "level" - } - }, - //default setting of excheck - _setting = { - // 配置检查选项 - check: { - // 是否启用检查功能,默认为false - enable: false, - // 是否自动触发检查,默认为false - autoCheckTrigger: false, - // 设置复选框的样式,使用常量中的样式定义 - chkStyle: _consts.checkbox.STYLE, - // 是否不继承未选中状态,默认为false - nocheckInherit: false, - // 是否不继承禁用状态,默认为false - chkDisabledInherit: false, - // 设置单选按钮的类型,使用常量中定义的类型 - radioType: _consts.radio.TYPE_LEVEL, - // 设置复选框类型,"Y"和"N"都对应到"ps" - chkboxType: { - "Y": "ps", - "N": "ps" - } - }, - data: { - key: { - checked: "checked" // 定义节点是否被选中的键名 - } - }, - callback: { - beforeCheck: null, // 在节点选中前执行的回调函数 - onCheck: null // 在节点选中后执行的回调函数 - } - }, - // default root of excheck - _initRoot = function (setting) { - var r = data.getRoot(setting); // 获取树的根节点 - r.radioCheckedList = []; // 初始化根节点的单选列表为空数组 - }, - // default cache of excheck - _initCache = function (treeId) { - // 初始化缓存,当前未实现具体逻辑 - }, - // default bind event of excheck - _bindEvent = function (setting) { - var o = setting.treeObj, // 获取树对象 - c = consts.event; // 获取事件常量 - o.bind(c.CHECK, function (event, srcEvent, treeId, node) { - event.srcEvent = srcEvent; // 将源事件附加到事件对象上 - tools.apply(setting.callback.onCheck, [event, treeId, node]); // 调用选中后的回调函数 - }); - }, - _unbindEvent = function (setting) { - // 获取树对象 - var o = setting.treeObj, - // 获取事件常量 - c = consts.event; - // 解绑CHECK事件 - o.unbind(c.CHECK); - }, - //default event proxy of excheck - _eventProxy = function (e) { - // 获取事件目标元素 - var target = e.target, - // 获取设置信息 - setting = data.getSetting(e.data.treeId), - tId = "", node = null, - nodeEventType = "", treeEventType = "", - nodeEventCallback = null, treeEventCallback = null; - - // 如果事件类型是mouseover - if (tools.eqs(e.type, "mouseover")) { - // 如果启用了复选框,并且目标元素是span标签且具有CHECK属性 - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) { - // 获取节点主DOM的ID - tId = tools.getNodeMainDom(target).id; - // 设置节点事件类型为mouseoverCheck - nodeEventType = "mouseoverCheck"; - } - } else if (tools.eqs(e.type, "mouseout")) { - // 如果事件类型是mouseout - // 如果启用了复选框,并且目标元素是span标签且具有CHECK属性 - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) { - // 获取节点主DOM的ID - tId = tools.getNodeMainDom(target).id; - // 设置节点事件类型为mouseoutCheck - nodeEventType = "mouseoutCheck"; - } - } else if (tools.eqs(e.type, "click")) { - // 如果事件类型是click - // 如果启用了复选框,并且目标元素是span标签且具有CHECK属性 - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) { - // 获取节点主DOM的ID - tId = tools.getNodeMainDom(target).id; - // 设置节点事件类型为checkNode - nodeEventType = "checkNode"; - } - } - // 检查tId数组的长度是否大于0 - if (tId.length > 0) { - // 从缓存中获取节点对象 - node = data.getNodeCache(setting, tId); - // 根据节点事件类型选择相应的回调函数 - switch (nodeEventType) { - // 如果事件类型是"checkNode",则使用_handler.onCheckNode作为回调函数 - case "checkNode": - nodeEventCallback = _handler.onCheckNode; - break; - // 如果事件类型是"mouseoverCheck",则使用_handler.onMouseoverCheck作为回调函数 - case "mouseoverCheck": - nodeEventCallback = _handler.onMouseoverCheck; - break; - // 如果事件类型是"mouseoutCheck",则使用_handler.onMouseoutCheck作为回调函数 - case "mouseoutCheck": - nodeEventCallback = _handler.onMouseoutCheck; - break; - } - } - var proxyResult = { - // 如果nodeEventType是"checkNode",则stop为true,否则为false - stop: nodeEventType === "checkNode", - // 当前节点对象 - node: node, - // 节点事件类型 - nodeEventType: nodeEventType, - // 节点事件回调函数 - nodeEventCallback: nodeEventCallback, - // 树事件类型 - treeEventType: treeEventType, - // 树事件回调函数 - treeEventCallback: treeEventCallback - }; - // 返回包含上述属性的对象 - return proxyResult - }, - //default init node of excheck - _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { - // 如果节点不存在,直接返回 - if (!n) return; - - // 获取节点的选中状态 - var checked = data.nodeChecked(setting, n); - - // 保存节点的旧选中状态 - n.checkedOld = checked; - - // 如果节点的nocheck属性是字符串类型,将其转换为布尔值 - if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true"); - - // 设置节点的nocheck属性,如果父节点存在且继承父节点的nocheck属性,则使用父节点的值 - n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck); - - // 如果节点的chkDisabled属性是字符串类型,将其转换为布尔值 - if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true"); - - // 设置节点的chkDisabled属性,如果父节点存在且继承父节点的chkDisabled属性,则使用父节点的值 - n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled); - - // 如果节点的halfCheck属性是字符串类型,将其转换为布尔值 - if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true"); - - // 设置节点的halfCheck属性为布尔值 - n.halfCheck = !!n.halfCheck; - - // 初始化子节点的状态为-1(未定义) - n.check_Child_State = -1; - - // 初始化节点的焦点状态为false - n.check_Focus = false; - - // 定义一个方法来获取节点的选中状态 - n.getCheckStatus = function () { - return data.getCheckStatus(setting, n); - }; - } - - if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && checked) { - // 获取根节点数据 - var r = data.getRoot(setting); - // 将当前节点添加到已选中的单选按钮列表中 - r.radioCheckedList.push(n); - } - //add dom for check - _beforeA = function (setting, node, html) { - // 检查是否启用了check功能 - if (setting.check.enable) { - // 调用makeChkFlag方法,为节点生成check标记 - data.makeChkFlag(setting, node); - // 将生成的HTML片段推入html数组中 - html.push(""); - } - }, - //update zTreeObj, add method of check - _zTreeTools = function (setting, zTreeTools) { - // 定义一个方法,用于检查节点的状态 - zTreeTools.checkNode = function (node, checked, checkTypeFlag, callbackFlag) { - // 获取当前节点的选中状态 - var nodeChecked = data.nodeChecked(setting, node); - // 如果节点被禁用,则直接返回 - if (node.chkDisabled === true) return; - // 如果checked参数不是布尔值,则取反当前节点的选中状态 - if (checked !== true && checked !== false) { - checked = !nodeChecked; - } - // 确保callbackFlag为布尔值 - callbackFlag = !!callbackFlag; - - // 如果节点的选中状态没有变化且不需要回调,则直接返回 - if (nodeChecked === checked && !checkTypeFlag) { - return; - // 如果需要回调且beforeCheck回调函数返回false,则直接返回 - } else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) { - return; - } - // 检查用户是否有权限进行操作,并且是否启用了节点选中功能,以及节点是否没有被禁用选中 - if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) { - // 更新节点的选中状态 - data.nodeChecked(setting, node, checked); - // 获取节点对应的复选框对象 - var checkObj = $$(node, consts.id.CHECK, this.setting); - // 如果需要检查类型标志或节点样式为单选,则更新节点关系 - if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); - // 设置复选框的样式 - view.setChkClass(this.setting, checkObj, node); - // 修复父节点的复选框样式 - view.repairParentChkClassWithSelf(this.setting, node); - // 如果需要回调,则触发CHECK事件 - if (callbackFlag) { - this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]); - } - } - } - - zTreeTools.checkAllNodes = function (checked) { - // 调用view对象的repairAllChk方法,修复所有节点的选中状态 - view.repairAllChk(this.setting, !!checked); - } - - zTreeTools.getCheckedNodes = function (checked) { - // 如果checked参数不为false,则将其转换为布尔值true - checked = (checked !== false); - // 获取根节点的所有子节点 - var children = data.nodeChildren(setting, data.getRoot(this.setting)); - // 返回树中所有被选中的节点 - return data.getTreeCheckedNodes(this.setting, children, checked); - } - - zTreeTools.getChangeCheckedNodes = function () { - // 获取根节点的所有子节点 - var children = data.nodeChildren(setting, data.getRoot(this.setting)); - // 返回树中所有改变选中状态的节点 - return data.getTreeChangeCheckedNodes(this.setting, children); - } - - zTreeTools.setChkDisabled = function (node, disabled, inheritParent, inheritChildren) { - // 将disabled参数转换为布尔值 - disabled = !!disabled; - // 将inheritParent参数转换为布尔值 - inheritParent = !!inheritParent; - // 将inheritChildren参数转换为布尔值 - inheritChildren = !!inheritChildren; - // 修复子节点的禁用状态 - view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren); - // 修复父节点的禁用状态 - view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent); - } - - var _updateNode = zTreeTools.updateNode; - zTreeTools.updateNode = function (node, checkTypeFlag) { - // 如果存在原始的updateNode方法,则调用它 - if (_updateNode) _updateNode.apply(zTreeTools, arguments); - // 如果节点不存在或检查功能未启用,则直接返回 - if (!node || !this.setting.check.enable) return; - // 获取节点对应的jQuery对象 - var nObj = $$(node, this.setting); - // 如果节点存在且用户有权限操作 - if (nObj.get(0) && tools.uCanDo(this.setting)) { - // 获取节点的复选框对象 - var checkObj = $$(node, consts.id.CHECK, this.setting); - // 如果checkTypeFlag为true或复选框样式为单选按钮 - if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) - // 修复节点的选中关系 - view.checkNodeRelation(this.setting, node); - // 设置复选框的CSS类 - view.setChkClass(this.setting, checkObj, node); - // 修复父节点的CSS类 - view.repairParentChkClassWithSelf(this.setting, node); - } - } - }, - //method of operate data - _data = { - // 获取选中的单选框列表 - getRadioCheckedList: function (setting) { - // 获取根节点的单选框选中列表 - var checkedList = data.getRoot(setting).radioCheckedList; - // 遍历选中列表,检查每个节点是否在缓存中存在 - for (var i = 0, j = checkedList.length; i < j; i++) { - // 如果节点不在缓存中,则从选中列表中移除 - if (!data.getNodeCache(setting, checkedList[i].tId)) { - checkedList.splice(i, 1); - i--; - j--; - } - } - // 返回处理后的选中列表 - return checkedList; - }, - - // 获取节点的选中状态 - getCheckStatus: function (setting, node) { - // 如果未启用选中功能或节点不可选中,则返回null - if (!setting.check.enable || node.nocheck || node.chkDisabled) return null; - // 获取节点是否被选中的状态 - var checked = data.nodeChecked(setting, node), - r = { - checked: checked, - // 根据不同的选中样式和子节点状态计算半选状态 - half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (checked ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0))) - }; - // 返回选中状态对象 - return r; - }, - - // 获取树形结构中所有选中的节点 - getTreeCheckedNodes: function (setting, nodes, checked, results) { - // 如果节点列表为空,则返回空数组 - if (!nodes) return []; - // 判断是否只允许选择一个节点(单选模式) - var onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL); - // 初始化结果数组 - results = !results ? [] : results; - // 遍历节点列表 - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - // 获取当前节点是否被选中 - var nodeChecked = data.nodeChecked(setting, node); - // 如果节点可选中且未禁用,并且其选中状态与目标状态一致,则将其加入结果数组 - if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked == checked) { - results.push(node); - // 如果只允许选择一个节点,则找到后立即退出循环 - if (onlyOne) { - break; - } - } - // 递归处理子节点 - data.getTreeCheckedNodes(setting, children, checked, results); - // 如果只允许选择一个节点,且已找到符合条件的节点,则退出循环 - if (onlyOne && results.length > 0) { - break; - } - } - // 返回结果数组 - return results; - }, - getTreeChangeCheckedNodes: function (setting, nodes, results) { - // 如果节点为空,返回空数组 - if (!nodes) return []; - // 如果结果未定义,初始化为空数组 - results = !results ? [] : results; - // 遍历所有节点 - for (var i = 0, l = nodes.length; i < l; i++) { - // 获取当前节点 - var node = nodes[i]; - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - // 检查当前节点是否被选中 - var nodeChecked = data.nodeChecked(setting, node); - // 如果节点没有被禁用且选中状态发生变化,则将节点加入结果数组 - if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked != node.checkedOld) { - results.push(node); - } - // 递归处理子节点 - data.getTreeChangeCheckedNodes(setting, children, results); - } - // 返回结果数组 - return results; - }, - /** - * 生成节点的检查标志。 - * @param {Object} setting - 配置对象,包含树形结构的相关设置。 - * @param {Object} node - 当前处理的节点对象。 - */ - makeChkFlag: function (setting, node) { - // 如果节点不存在,直接返回 - if (!node) return; - - // 初始化检查标志为-1 - var chkFlag = -1; - - // 获取节点的子节点列表 - var children = data.nodeChildren(setting, node); - - // 如果存在子节点 - if (children) { - // 遍历所有子节点 - for (var i = 0, l = children.length; i < l; i++) { - var cNode = children[i]; // 当前子节点 - var nodeChecked = data.nodeChecked(setting, cNode); // 判断子节点是否被选中 - var tmp = -1; // 临时变量,用于存储子节点的状态 - - // 如果检查样式是单选框 - if (setting.check.chkStyle == consts.radio.STYLE) { - // 如果子节点不可检查或禁用,则使用其子状态 - if (cNode.nocheck === true || cNode.chkDisabled === true) { - tmp = cNode.check_Child_State; - } else if (cNode.halfCheck === true) { - // 如果子节点半选,则状态为2 - tmp = 2; - } else if (nodeChecked) { - // 如果子节点被选中,则状态为2 - tmp = 2; - } else { - // 根据子节点的子状态决定状态 - tmp = cNode.check_Child_State > 0 ? 2 : 0; - } - // 如果状态为2,更新检查标志并退出循环 - if (tmp == 2) { - chkFlag = 2; - break; - } else if (tmp == 0) { - // 如果状态为0,更新检查标志为0 - chkFlag = 0; - } - } else if (setting.check.chkStyle == consts.checkbox.STYLE) { - // 如果检查样式是复选框 - if (cNode.nocheck === true || cNode.chkDisabled === true) { - tmp = cNode.check_Child_State; - } else if (cNode.halfCheck === true) { - // 如果子节点半选,则状态为1 - tmp = 1; - } else if (nodeChecked) { - // 根据子节点的子状态决定状态 - tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1; - } else { - // 根据子节点的子状态决定状态 - tmp = (cNode.check_Child_State > 0) ? 1 : 0; - } - // 如果状态为1,更新检查标志并退出循环 - if (tmp === 1) { - chkFlag = 1; - break; - } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) { - // 如果状态为2且之前有其他状态,更新检查标志为1并退出循环 - chkFlag = 1; - break; - } else if (chkFlag === 2 && tmp > -1 && tmp < 2) { - // 如果之前状态为2且当前状态在0和2之间,更新检查标志为1并退出循环 - chkFlag = 1; - break; - } else if (tmp > -1) { - // 更新检查标志为当前状态 - chkFlag = tmp; - } - } - } - } - // 将计算得到的检查标志赋值给节点的check_Child_State属性 - node.check_Child_State = chkFlag; - } - //method of event proxy - _event = {}, - // 事件处理程序的方法集合 - _handler = { - /** - * 处理节点选中事件的函数 - * @param {Object} event - 事件对象 - * @param {Object} node - 被操作的节点对象 - * @returns {boolean} - 返回是否成功处理事件 - */ - onCheckNode: function (event, node) { - // 如果节点被禁用,则直接返回false - if (node.chkDisabled === true) return false; - // 获取当前树的设置信息 - var setting = data.getSetting(event.data.treeId); - // 调用beforeCheck回调函数,如果返回false,则终止操作 - if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true; - // 获取节点当前的选中状态 - var nodeChecked = data.nodeChecked(setting, node); - // 切换节点的选中状态 - data.nodeChecked(setting, node, !nodeChecked); - // 更新节点关系 - view.checkNodeRelation(setting, node); - // 获取节点对应的复选框元素 - var checkObj = $$(node, consts.id.CHECK, setting); - // 设置复选框的样式 - view.setChkClass(setting, checkObj, node); - // 修复父节点的复选框样式 - view.repairParentChkClassWithSelf(setting, node); - // 触发CHECK事件 - setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]); - return true; - }, - /** - * 处理鼠标悬停在复选框上的事件 - * @param {Object} event - 事件对象 - * @param {Object} node - 被操作的节点对象 - * @returns {boolean} - 返回是否成功处理事件 - */ - onMouseoverCheck: function (event, node) { - // 如果节点被禁用,则直接返回false - if (node.chkDisabled === true) return false; - // 获取当前树的设置信息和复选框元素 - var setting = data.getSetting(event.data.treeId), - checkObj = $$(node, consts.id.CHECK, setting); - // 设置节点的check_Focus属性为true - node.check_Focus = true; - // 设置复选框的样式 - view.setChkClass(setting, checkObj, node); - return true; - }, - /** - * 处理鼠标移出复选框的事件 - * @param {Object} event - 事件对象 - * @param {Object} node - 被操作的节点对象 - * @returns {boolean} - 返回是否成功处理事件 - */ - onMouseoutCheck: function (event, node) { - // 如果节点被禁用,则直接返回false - if (node.chkDisabled === true) return false; - // 获取当前树的设置信息和复选框元素 - var setting = data.getSetting(event.data.treeId), - checkObj = $$(node, consts.id.CHECK, setting); - // 设置节点的check_Focus属性为false - node.check_Focus = false; - // 设置复选框的样式 - view.setChkClass(setting, checkObj, node); - return true; - } - }, - //method of tools for zTree - _tools = {}, - // 操作ztree DOM的方法 - _view = { - /** - * 检查节点关系,确保单选模式下只有一个节点被选中 - * @param {Object} setting - ztree的配置对象 - * @param {Object} node - 当前操作的节点对象 - */ - checkNodeRelation: function (setting, node) { - var pNode, i, l, - r = consts.radio; // 获取常量中的单选模式配置 - var nodeChecked = data.nodeChecked(setting, node); // 判断当前节点是否被选中 - if (setting.check.chkStyle == r.STYLE) { // 如果配置为单选模式 - var checkedList = data.getRadioCheckedList(setting); // 获取已选中的单选节点列表 - if (nodeChecked) { // 如果当前节点被选中 - if (setting.check.radioType == r.TYPE_ALL) { // 如果单选类型为全选 - for (i = checkedList.length - 1; i >= 0; i--) { // 遍历已选中的单选节点列表 - pNode = checkedList[i]; // 获取已选中的节点 - var pNodeChecked = data.nodeChecked(setting, pNode); // 判断已选中的节点是否被选中 - if (pNodeChecked && pNode != node) { // 如果已选中的节点被选中且不是当前节点 - data.nodeChecked(setting, pNode, false); // 取消已选中节点的选中状态 - checkedList.splice(i, 1); // 从已选中列表中移除该节点 - - view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); // 更新节点的样式 - if (pNode.parentTId != node.parentTId) { // 如果父节点不同 - view.repairParentChkClassWithSelf(setting, pNode); // 修复父节点的样式 - } - } - } - // 将节点添加到已选中列表中 - checkedList.push(node); - } else { - // 获取父节点,如果当前节点有父节点则获取其父节点,否则获取根节点 - var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); - // 获取父节点的所有子节点 - var children = data.nodeChildren(setting, parentNode); - // 遍历所有子节点 - for (i = 0, l = children.length; i < l; i++) { - pNode = children[i]; - // 检查子节点是否被选中 - var pNodeChecked = data.nodeChecked(setting, pNode); - // 如果子节点被选中且不是当前节点,则取消其选中状态并更新视图 - if (pNodeChecked && pNode != node) { - data.nodeChecked(setting, pNode, false); - view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); - } - } - } else if (setting.check.radioType == r.TYPE_ALL) { - // 如果设置为单选类型,则从已选中列表中移除当前节点 - for (i = 0, l = checkedList.length; i < l; i++) { - if (node == checkedList[i]) { - checkedList.splice(i, 1); - break; - } - } - } - - } else { - // 获取当前节点的子节点 - var children = data.nodeChildren(setting, node); - - // 如果当前节点被选中,并且没有子节点或子节点为空,或者设置中允许部分选中状态 - if (nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.Y.indexOf("s") > -1)) { - // 设置子节点的复选框为选中状态 - view.setSonNodeCheckBox(setting, node, true); - } - - // 如果当前节点未被选中,并且没有子节点或子节点为空,或者设置中允许部分未选中状态 - if (!nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.N.indexOf("s") > -1)) { - // 设置子节点的复选框为未选中状态 - view.setSonNodeCheckBox(setting, node, false); - } - - // 如果当前节点被选中,并且设置中允许父节点选中状态 - if (nodeChecked && setting.check.chkboxType.Y.indexOf("p") > -1) { - // 设置父节点的复选框为选中状态 - view.setParentNodeCheckBox(setting, node, true); - } - - // 如果当前节点未被选中,并且设置中允许父节点未选中状态 - if (!nodeChecked && setting.check.chkboxType.N.indexOf("p") > -1) { - // 设置父节点的复选框为未选中状态 - view.setParentNodeCheckBox(setting, node, false); - } - } - }, - makeChkClass: function (setting, node) { - // 获取复选框和单选按钮的常量 - var c = consts.checkbox, r = consts.radio, - fullStyle = ""; - // 检查节点是否被选中 - var nodeChecked = data.nodeChecked(setting, node); - // 如果节点被禁用,设置样式为禁用状态 - if (node.chkDisabled === true) { - fullStyle = c.DISABLED; - // 如果节点处于半选状态,设置样式为部分选中 - } else if (node.halfCheck) { - fullStyle = c.PART; - // 如果设置为单选按钮样式,根据子节点状态设置样式 - } else if (setting.check.chkStyle == r.STYLE) { - fullStyle = (node.check_Child_State < 1) ? c.FULL : c.PART; - // 根据节点是否选中和子节点状态设置样式 - } else { - fullStyle = nodeChecked ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL : c.PART) : ((node.check_Child_State < 1) ? c.FULL : c.PART); - } - // 生成复选框的类名 - var chkName = setting.check.chkStyle + "_" + (nodeChecked ? c.TRUE : c.FALSE) + "_" + fullStyle; - // 如果节点有焦点且未被禁用,添加焦点样式 - chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; - // 返回完整的类名字符串 - return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName; - }, - /** - * 修复所有复选框的状态 - * @param {Object} setting - 配置对象 - * @param {Boolean} checked - 是否选中 - */ - repairAllChk: function (setting, checked) { - // 如果启用了复选框并且样式为复选框样式 - if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) { - // 获取根节点 - var root = data.getRoot(setting); - // 获取根节点的所有子节点 - var children = data.nodeChildren(setting, root); - // 遍历所有子节点 - for (var i = 0, l = children.length; i < l; i++) { - var node = children[i]; - // 如果节点没有被禁用且没有禁止选中 - if (node.nocheck !== true && node.chkDisabled !== true) { - // 设置节点的选中状态 - data.nodeChecked(setting, node, checked); - } - // 更新子节点的复选框状态 - view.setSonNodeCheckBox(setting, node, checked); - } - } - }, - /** - * 修复单个节点的复选框样式 - * @param {Object} setting - 配置对象 - * @param {Object} node - 节点对象 - */ - repairChkClass: function (setting, node) { - // 如果节点不存在,直接返回 - if (!node) return; - // 标记节点的复选框状态 - data.makeChkFlag(setting, node); - // 如果节点没有被禁止选中 - if (node.nocheck !== true) { - // 获取节点的复选框对象 - var checkObj = $$(node, consts.id.CHECK, setting); - // 设置复选框的样式 - view.setChkClass(setting, checkObj, node); - } - }, - repairParentChkClass: function (setting, node) { - // 如果节点不存在或没有父节点ID,则直接返回 - if (!node || !node.parentTId) return; - // 获取父节点 - var pNode = node.getParentNode(); - // 修复父节点的复选框样式 - view.repairChkClass(setting, pNode); - // 递归修复父节点的父节点的复选框样式 - view.repairParentChkClass(setting, pNode); - }, - - repairParentChkClassWithSelf: function (setting, node) { - // 如果节点不存在,则直接返回 - if (!node) return; - // 获取子节点列表 - var children = data.nodeChildren(setting, node); - // 如果存在子节点,则修复第一个子节点的父节点复选框样式 - if (children && children.length > 0) { - view.repairParentChkClass(setting, children[0]); - } else { - // 否则修复当前节点的父节点复选框样式 - view.repairParentChkClass(setting, node); - } - }, - - repairSonChkDisabled: function (setting, node, chkDisabled, inherit) { - // 如果节点不存在,则直接返回 - if (!node) return; - // 如果节点的chkDisabled属性与传入值不同,则更新该属性 - if (node.chkDisabled != chkDisabled) { - node.chkDisabled = chkDisabled; - } - // 修复当前节点的复选框样式 - view.repairChkClass(setting, node); - // 获取子节点列表 - var children = data.nodeChildren(setting, node); - // 如果存在子节点且需要继承,则递归修复所有子节点的chkDisabled属性和复选框样式 - if (children && inherit) { - for (var i = 0, l = children.length; i < l; i++) { - var sNode = children[i]; - view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit); - } - } - }, - - repairParentChkDisabled: function (setting, node, chkDisabled, inherit) { - // 如果节点不存在,则直接返回 - if (!node) return; - // 如果节点的chkDisabled属性与传入值不同且需要继承,则更新该属性 - if (node.chkDisabled != chkDisabled && inherit) { - node.chkDisabled = chkDisabled; - } - // 修复当前节点的复选框样式 - view.repairChkClass(setting, node); - // 递归修复父节点的chkDisabled属性和复选框样式 - view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit); - }, - setChkClass: function (setting, obj, node) { - // 如果对象不存在,直接返回 - if (!obj) return; - // 如果节点的nocheck属性为true,隐藏复选框 - if (node.nocheck === true) { - obj.hide(); - } else { - // 否则显示复选框 - obj.show(); - } - // 设置复选框的class属性 - obj.attr('class', view.makeChkClass(setting, node)); - }, - setParentNodeCheckBox: function (setting, node, value, srcNode) { - // 获取当前节点的复选框对象 - var checkObj = $$(node, consts.id.CHECK, setting); - // 如果没有传入srcNode,则将当前节点赋值给srcNode - if (!srcNode) srcNode = node; - // 更新节点的检查状态标志 - data.makeChkFlag(setting, node); - // 如果节点没有禁用检查且未设置为不检查 - if (node.nocheck !== true && node.chkDisabled !== true) { - // 设置节点的选中状态 - data.nodeChecked(setting, node, value); - // 更新复选框的样式和类名 - view.setChkClass(setting, checkObj, node); - // 如果自动检查触发开启且当前节点不是源节点,触发CHECK事件 - if (setting.check.autoCheckTrigger && node != srcNode) { - setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); - } - } - // 如果节点有父节点 - if (node.parentTId) { - var pSign = true; - // 如果值为false - if (!value) { - // 获取父节点的所有子节点 - var pNodes = data.nodeChildren(setting, node.getParentNode()); - // 遍历所有子节点 - for (var i = 0, l = pNodes.length; i < l; i++) { - var pNode = pNodes[i]; - // 获取子节点的选中状态 - var nodeChecked = data.nodeChecked(setting, pNode); - // 如果子节点未被禁用且选中,或者子节点被禁用但有子节点被选中,则pSign设为false并跳出循环 - if ((pNode.nocheck !== true && pNode.chkDisabled !== true && nodeChecked) - || ((pNode.nocheck === true || pNode.chkDisabled === true) && pNode.check_Child_State > 0)) { - pSign = false; - break; - } - } - } - if (pSign) { - // 如果 pSign 为真,设置父节点的复选框状态 - view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode); - } - }, - setSonNodeCheckBox: function (setting, node, value, srcNode) { - // 如果节点不存在,直接返回 - if (!node) return; - // 获取当前节点的复选框对象 - var checkObj = $$(node, consts.id.CHECK, setting); - // 如果源节点未定义,则将当前节点设为源节点 - if (!srcNode) srcNode = node; - - // 初始化 hasDisable 标志位,用于记录子节点是否有禁用的复选框 - var hasDisable = false; - // 获取当前节点的子节点列表 - var children = data.nodeChildren(setting, node); - if (children) { - // 遍历所有子节点 - for (var i = 0, l = children.length; i < l; i++) { - var sNode = children[i]; - // 递归设置子节点的复选框状态 - view.setSonNodeCheckBox(setting, sNode, value, srcNode); - // 如果子节点被禁用,则设置 hasDisable 为 true - if (sNode.chkDisabled === true) hasDisable = true; - } - } - - // 如果当前节点不是根节点且未被禁用 - if (node != data.getRoot(setting) && node.chkDisabled !== true) { - // 如果存在禁用的子节点且当前节点未被禁用,更新当前节点的复选框状态 - if (hasDisable && node.nocheck !== true) { - data.makeChkFlag(setting, node); - } - // 如果当前节点未被禁用且未设置为不检查 - if (node.nocheck !== true && node.chkDisabled !== true) { - // 设置当前节点的选中状态 - data.nodeChecked(setting, node, value); - // 根据子节点的状态更新当前节点的子节点状态 - if (!hasDisable) node.check_Child_State = (children && children.length > 0) ? (value ? 2 : 0) : -1; - } else { - // 如果当前节点被禁用或设置为不检查,则将其子节点状态设为 -1 - node.check_Child_State = -1; - } - // 更新当前节点的复选框样式 - view.setChkClass(setting, checkObj, node); - // 如果自动触发检查事件,并且当前节点不是源节点且未被禁用或设置为不检查,则触发检查事件 - if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) { - setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); - } - } - - } - }, - - _z = { - tools: _tools, - view: _view, - event: _event, - data: _data - }; - // 将常量对象扩展到jQuery的zTree插件中 - $.extend(true, $.fn.zTree.consts, _consts); - // 将工具对象扩展到jQuery的zTree插件中 - $.extend(true, $.fn.zTree._z, _z); - - var zt = $.fn.zTree, - tools = zt._z.tools, - consts = zt.consts, - view = zt._z.view, - data = zt._z.data, - event = zt._z.event, - $$ = tools.$; - - /** - * 设置或获取节点的选中状态 - * @param {Object} setting - 配置对象 - * @param {Object} node - 节点对象 - * @param {boolean|string} newChecked - 新的选中状态,可以是布尔值或字符串 - * @returns {boolean} - 返回节点的最终选中状态 - */ - data.nodeChecked = function (setting, node, newChecked) { - // 如果节点不存在,返回false - if (!node) { - return false; - } - var key = setting.data.key.checked; - // 如果newChecked被定义了 - if (typeof newChecked !== 'undefined') { - // 如果newChecked是字符串类型,将其转换为布尔值 - if (typeof newChecked === "string") { - newChecked = tools.eqs(newChecked, "true"); - } - // 将newChecked转换为布尔值并赋值给节点的key属性 - newChecked = !!newChecked; - node[key] = newChecked; - } else if (typeof node[key] == "string"){ - // 如果节点的key属性是字符串类型,将其转换为布尔值 - node[key] = tools.eqs(node[key], "true"); - } else { - // 否则,将节点的key属性转换为布尔值 - node[key] = !!node[key]; - } - // 返回节点的最终选中状态 - return node[key]; - }; - - // 调用exSetting方法,传入_setting参数进行设置 - data.exSetting(_setting); - - // 添加初始化绑定事件,传入_bindEvent作为回调函数 - data.addInitBind(_bindEvent); - - // 添加初始化解绑事件,传入_unbindEvent作为回调函数 - data.addInitUnBind(_unbindEvent); - - // 添加初始化缓存,传入_initCache作为回调函数 - data.addInitCache(_initCache); - - // 添加初始化节点,传入_initNode作为回调函数 - data.addInitNode(_initNode); - - // 添加初始化代理,传入_eventProxy作为回调函数,并设置第二个参数为true - data.addInitProxy(_eventProxy, true); - - // 添加初始化根节点,传入_initRoot作为回调函数 - data.addInitRoot(_initRoot); - - // 添加在A操作之前的回调函数,传入_beforeA作为回调函数 - data.addBeforeA(_beforeA); - - // 添加ZTree工具,传入_zTreeTools作为回调函数 - data.addZTreeTools(_zTreeTools); - var _createNodes = view.createNodes; - view.createNodes = function (setting, level, nodes, parentNode, index) { - // 如果存在原始的 createNodes 方法,则调用它 - if (_createNodes) _createNodes.apply(view, arguments); - // 如果没有节点需要创建,直接返回 - if (!nodes) return; - // 修复父节点的选中状态类 - view.repairParentChkClassWithSelf(setting, parentNode); - } - - var _removeNode = view.removeNode; - view.removeNode = function (setting, node) { - // 获取要删除节点的父节点 - var parentNode = node.getParentNode(); - // 如果存在原始的 removeNode 方法,则调用它 - if (_removeNode) _removeNode.apply(view, arguments); - // 如果节点或其父节点不存在,直接返回 - if (!node || !parentNode) return; - // 修复父节点的选中状态类 - view.repairChkClass(setting, parentNode); - // 修复父节点的选中状态类(与上一个修复方法可能不同) - view.repairParentChkClass(setting, parentNode); - } - - var _appendNodes = view.appendNodes; // 保存原始的appendNodes方法 - view.appendNodes = function (setting, level, nodes, parentNode, index, initFlag, openFlag) { - // 定义新的appendNodes方法,接收多个参数 - var html = ""; // 初始化html变量为空字符串 - if (_appendNodes) { - // 如果存在原始的appendNodes方法,则调用它并传递所有参数 - html = _appendNodes.apply(view, arguments); - } - if (parentNode) { - // 如果parentNode存在,则调用makeChkFlag方法 - data.makeChkFlag(setting, parentNode); - } - return html; // 返回生成的html内容 - } - })(jQuery); // 立即执行函数,传入jQuery对象 -/* - * JQuery zTree exedit - * v3.5.46 - * http://treejs.cn/ - * - * Copyright (c) 2010 Hunter.z - * - * Licensed same as jquery - MIT License - * http://www.opensource.org/licenses/mit-license.php - * - * Date: 2020-11-21 - */ - -(function ($) { - // 定义exedit的默认常量 - var _consts = { - event: { - // 拖拽事件 - DRAG: "ztree_drag", - // 放置事件 - DROP: "ztree_drop", - // 重命名事件 - RENAME: "ztree_rename", - // 拖动移动事件 - DRAGMOVE: "ztree_dragmove" - }, - id: { - // 编辑状态ID - EDIT: "_edit", - // 输入框ID - INPUT: "_input", - // 删除按钮ID - REMOVE: "_remove" - }, - move: { - // 内部移动类型 - TYPE_INNER: "inner", - // 上一个节点移动类型 - TYPE_PREV: "prev", - // 下一个节点移动类型 - TYPE_NEXT: "next" - }, - node: { - // 当前选中节点编辑状态 - CURSELECTED_EDIT: "curSelectedNode_Edit", - // 临时目标树ID - TMPTARGET_TREE: "tmpTargetzTree", - // 临时目标节点ID - TMPTARGET_NODE: "tmpTargetNode" - } - }, - // 定义exedit的默认设置 - _setting = { - edit: { - // 是否启用编辑功能 - enable: false, - // 是否在编辑时全选节点名称 - editNameSelectAll: false, - // 是否显示删除按钮 - showRemoveBtn: true, - // 是否显示重命名按钮 - showRenameBtn: true, - // 删除按钮的标题 - removeTitle: "remove", - // 重命名按钮的标题 - renameTitle: "rename", - drag: { - // 自动展开触发器 - autoExpandTrigger: false, - // 是否允许复制操作 - isCopy: true, - // 是否允许移动操作 - isMove: true, - // 是否允许移动到前一个节点 - prev: true, - // 是否允许移动到下一个节点 - next: true, - // 是否允许移动到内部节点 - inner: true, - // 最小移动尺寸 - minMoveSize: 5, - // 最大边界值 - borderMax: 10, - // 最小边界值 - borderMin: -5, - // 最大显示节点数 - maxShowNodeNum: 5, - // 自动打开时间(毫秒) - autoOpenTime: 500 - } - }, - view: { - // 添加悬停DOM元素的回调函数,初始值为null - addHoverDom: null, - // 移除悬停DOM元素的回调函数,初始值为null - removeHoverDom: null - }, - callback: { - // 拖动节点前的回调函数,初始值为null - beforeDrag: null, - // 打开拖动节点前的回调函数,初始值为null - beforeDragOpen: null, - // 放置节点前的回调函数,初始值为null - beforeDrop: null, - // 编辑节点名称前的回调函数,初始值为null - beforeEditName: null, - // 重命名节点前的回调函数,初始值为null - beforeRename: null, - // 拖动节点时的回调函数,初始值为null - onDrag: null, - // 拖动节点移动时的回调函数,初始值为null - onDragMove: null, - // 放置节点后的回调函数,初始值为null - onDrop: null, - // 重命名节点后的回调函数,初始值为null - onRename: null - } - }, - //default root of exedit - _initRoot = function (setting) { - // 获取根节点对象 - var r = data.getRoot(setting), rs = data.getRoots(); - // 当前编辑的节点设为空 - r.curEditNode = null; - // 当前编辑的输入框设为空 - r.curEditInput = null; - // 当前悬停的节点设为空 - r.curHoverNode = null; - // 拖拽标志设为0 - r.dragFlag = 0; - // 初始化拖拽显示前的节点数组 - r.dragNodeShowBefore = []; - // 初始化拖拽遮罩列表 - r.dragMaskList = new Array(); - // 设置是否显示悬停的DOM元素 - rs.showHoverDom = true; - }, - //default cache of exedit - _initCache = function (treeId) { - // 初始化缓存,暂未实现具体逻辑 - }, - //default bind event of exedit - _bindEvent = function (setting) { - // 获取树对象 - var o = setting.treeObj; - // 获取事件常量 - var c = consts.event; - o.bind(c.RENAME, function (event, treeId, treeNode, isCancel) { - // 绑定重命名事件,调用回调函数 - tools.apply(setting.callback.onRename, [event, treeId, treeNode, isCancel]); - }); - - o.bind(c.DRAG, function (event, srcEvent, treeId, treeNodes) { - // 绑定拖拽事件,调用回调函数 - tools.apply(setting.callback.onDrag, [srcEvent, treeId, treeNodes]); - }); - - o.bind(c.DRAGMOVE, function (event, srcEvent, treeId, treeNodes) { - // 绑定拖拽移动事件,调用回调函数 - tools.apply(setting.callback.onDragMove, [srcEvent, treeId, treeNodes]); - }); - - o.bind(c.DROP, function (event, srcEvent, treeId, treeNodes, targetNode, moveType, isCopy) { - // 调用设置中的回调函数,处理节点拖放事件 - tools.apply(setting.callback.onDrop, [srcEvent, treeId, treeNodes, targetNode, moveType, isCopy]); - }); - }, - _unbindEvent = function (setting) { - // 获取树对象和常量 - var o = setting.treeObj; - var c = consts.event; - // 解绑重命名事件 - o.unbind(c.RENAME); - // 解绑拖拽开始事件 - o.unbind(c.DRAG); - // 解绑拖拽移动事件 - o.unbind(c.DRAGMOVE); - // 解绑拖拽放下事件 - o.unbind(c.DROP); - }, - //default event proxy of exedit - _eventProxy = function (e) { - // 获取事件目标、相关目标、设置等变量 - var target = e.target, - setting = data.getSetting(e.data.treeId), - relatedTarget = e.relatedTarget, - tId = "", node = null, - nodeEventType = "", treeEventType = "", - nodeEventCallback = null, treeEventCallback = null, - tmp = null; - - if (tools.eqs(e.type, "mouseover")) { - // 处理鼠标悬停事件,获取目标节点的ID和事件类型 - tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - if (tmp) { - tId = tools.getNodeMainDom(tmp).id; - nodeEventType = "hoverOverNode"; - } - } else if (tools.eqs(e.type, "mouseout")) { - // 处理鼠标移出事件,判断是否移出了节点范围 - tmp = tools.getMDom(setting, relatedTarget, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - if (!tmp) { - tId = "remove"; - nodeEventType = "hoverOutNode"; - } - } else if (tools.eqs(e.type, "mousedown")) { - // 处理鼠标按下事件,获取目标节点的ID和事件类型 - tmp = tools.getMDom(setting, target, [{tagName: "a", attrName: "treeNode" + consts.id.A}]); - if (tmp) { - tId = tools.getNodeMainDom(tmp).id; - nodeEventType = "mousedownNode"; - } - } - // 检查 tId 数组是否非空 - if (tId.length > 0) { - // 从缓存中获取节点对象 - node = data.getNodeCache(setting, tId); - // 根据节点事件类型选择相应的回调函数 - switch (nodeEventType) { - // 如果事件类型是鼠标按下节点 - case "mousedownNode" : - // 设置回调函数为鼠标按下节点的处理函数 - nodeEventCallback = _handler.onMousedownNode; - break; - // 如果事件类型是鼠标悬停到节点上 - case "hoverOverNode" : - // 设置回调函数为鼠标悬停到节点上的处理函数 - nodeEventCallback = _handler.onHoverOverNode; - break; - // 如果事件类型是鼠标移出节点 - case "hoverOutNode" : - // 设置回调函数为鼠标移出节点的处理函数 - nodeEventCallback = _handler.onHoverOutNode; - break; - } - } - var proxyResult = { - stop: false, // 初始化停止标志为false - node: node, // 当前节点 - nodeEventType: nodeEventType, // 节点事件类型 - nodeEventCallback: nodeEventCallback, // 节点事件回调函数 - treeEventType: treeEventType, // 树事件类型 - treeEventCallback: treeEventCallback // 树事件回调函数 - }; - return proxyResult // 返回代理结果对象 - }, - //default init node of exedit - _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { - if (!n) return; // 如果节点不存在,直接返回 - n.isHover = false; // 初始化节点的悬停状态为false - n.editNameFlag = false; // 初始化节点的编辑名称标志为false - }, - //update zTreeObj, add method of edit - _zTreeTools = function (setting, zTreeTools) { - zTreeTools.cancelEditName = function (newName) { - var root = data.getRoot(this.setting); // 获取根节点 - if (!root.curEditNode) return; // 如果没有正在编辑的节点,直接返回 - view.cancelCurEditNode(this.setting, newName ? newName : null, true); // 取消当前编辑的节点 - } - zTreeTools.copyNode = function (targetNode, node, moveType, isSilent) { - if (!node) return null; // 如果节点不存在,返回null - var isParent = data.nodeIsParent(setting, targetNode); // 判断目标节点是否是父节点 - if (targetNode && !isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) return null; // 如果目标节点不是父节点且不允许移动到叶子节点,返回null - var _this = this, - newNode = tools.clone(node); // 克隆新节点 - if (!targetNode) { - targetNode = null; // 如果目标节点不存在,设置为null - moveType = consts.move.TYPE_INNER; // 设置移动类型为内部移动 - } - if (moveType == consts.move.TYPE_INNER) { - function copyCallback() { - view.addNodes(_this.setting, targetNode, -1, [newNode], isSilent); // 添加新节点到目标节点 - } - - if (tools.canAsync(this.setting, targetNode)) { - view.asyncNode(this.setting, targetNode, isSilent, copyCallback); // 如果目标节点支持异步加载,则异步加载后执行回调 - } else { - copyCallback(); // 否则直接执行回调 - } - } else { - view.addNodes(this.setting, targetNode.parentNode, -1, [newNode], isSilent); // 添加新节点到目标节点的父节点 - view.moveNode(this.setting, targetNode, newNode, moveType, false, isSilent); // 移动目标节点到新节点位置 - } - return newNode; // 返回新节点 - } - zTreeTools.editName = function (node) { - if (!node || !node.tId || node !== data.getNodeCache(this.setting, node.tId)) return; // 如果节点不存在或节点ID无效或节点不在缓存中,直接返回 - if (node.parentTId) view.expandCollapseParentNode(this.setting, node.getParentNode(), true); // 如果节点有父节点,展开父节点 - view.editNode(this.setting, node) // 编辑节点名称 - } - zTreeTools.moveNode = function (targetNode, node, moveType, isSilent) { - if (!node) return node; // 如果节点不存在,直接返回节点 - var isParent = data.nodeIsParent(setting, targetNode); // 判断目标节点是否是父节点 - if (targetNode && !isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) { - return null; // 如果目标节点不是父节点且不允许移动到叶子节点,返回null - } else if (targetNode && ((node.parentTId == targetNode.tId && moveType == consts.move.TYPE_INNER) || $$(node, this.setting).find("#" + targetNode.tId).length > 0)) { - return null; // 如果目标节点是当前节点的父节点且移动类型为内部移动,或者目标节点包含当前节点,返回null - } else if (!targetNode) { - targetNode = null; // 如果目标节点不存在,设置为null - var _this = this; - - function moveCallback() { - // 调用view对象的moveNode方法,执行节点移动操作 - view.moveNode(_this.setting, targetNode, node, moveType, false, isSilent); - } - - // 判断是否可以异步处理节点移动,并且移动类型为内部移动 - if (tools.canAsync(this.setting, targetNode) && moveType === consts.move.TYPE_INNER) { - // 如果可以异步处理,则调用view对象的asyncNode方法进行异步节点移动 - view.asyncNode(this.setting, targetNode, isSilent, moveCallback); - } else { - // 否则直接调用moveCallback方法进行同步节点移动 - moveCallback(); - } - // 返回当前节点对象 - return node; - } - - zTreeTools.setEditable = function (editable) { - // 设置树的编辑状态 - this.setting.edit.enable = editable; - // 刷新树以应用新的编辑状态 - return this.refresh(); - } - }, - //method of operate data - _data = { - /** - * 设置子节点的层级 - * @param {Object} setting - 配置对象 - * @param {Object} parentNode - 父节点对象 - * @param {Object} node - 当前节点对象 - */ - setSonNodeLevel: function (setting, parentNode, node) { - // 如果当前节点不存在,直接返回 - if (!node) return; - // 获取当前节点的子节点列表 - var children = data.nodeChildren(setting, node); - // 设置当前节点的层级,如果存在父节点则层级加1,否则为0 - node.level = (parentNode) ? parentNode.level + 1 : 0; - // 如果子节点列表不存在,直接返回 - if (!children) return; - // 遍历所有子节点,递归设置每个子节点的层级 - for (var i = 0, l = children.length; i < l; i++) { - if (children[i]) data.setSonNodeLevel(setting, node, children[i]); - } - } - }, - //method of event proxy - _event = {}, - // 事件处理程序的方法 - _handler = { - /** - * 当鼠标悬停在节点上时触发的事件处理函数 - * @param {Object} event - 事件对象,包含事件相关的数据 - * @param {Object} node - 当前悬停的节点对象 - */ - onHoverOverNode: function (event, node) { - // 获取树的设置信息 - var setting = data.getSetting(event.data.treeId), - // 获取树的根节点 - root = data.getRoot(setting); - // 如果当前悬停的节点不是目标节点 - if (root.curHoverNode != node) { - // 调用onHoverOutNode方法处理之前的悬停节点 - _handler.onHoverOutNode(event); - } - // 更新当前悬停的节点为目标节点 - root.curHoverNode = node; - // 在视图中添加悬停效果的DOM元素 - view.addHoverDom(setting, node); - }, - /** - * 当鼠标移出节点时触发的事件处理函数 - * @param {Object} event - 事件对象,包含事件相关的数据 - * @param {Object} node - 当前移出的节点对象(可选) - */ - onHoverOutNode: function (event, node) { - // 获取树的设置信息 - var setting = data.getSetting(event.data.treeId), - // 获取树的根节点 - root = data.getRoot(setting); - // 如果当前有悬停的节点且该节点未被选中 - if (root.curHoverNode && !data.isSelectedNode(setting, root.curHoverNode)) { - // 从视图中移除悬停效果的DOM元素 - view.removeTreeDom(setting, root.curHoverNode); - // 清空当前悬停的节点 - root.curHoverNode = null; - } - }, - onMousedownNode: function (eventMouseDown, _node) { - var i, l, - setting = data.getSetting(eventMouseDown.data.treeId), - root = data.getRoot(setting), roots = data.getRoots(); - //right click can't drag & drop - if (eventMouseDown.button == 2 || !setting.edit.enable || (!setting.edit.drag.isCopy && !setting.edit.drag.isMove)) return true; - - //input of edit node name can't drag & drop - var target = eventMouseDown.target, - _nodes = data.getRoot(setting).curSelectedList, - nodes = []; - if (!data.isSelectedNode(setting, _node)) { - nodes = [_node]; - } else { - for (i = 0, l = _nodes.length; i < l; i++) { - if (_nodes[i].editNameFlag && tools.eqs(target.tagName, "input") && target.getAttribute("treeNode" + consts.id.INPUT) !== null) { - return true; - } - nodes.push(_nodes[i]); - if (nodes[0].parentTId !== _nodes[i].parentTId) { - nodes = [_node]; - break; - } - } - } - - view.editNodeBlur = true; // 设置编辑节点失去焦点标志为true - view.cancelCurEditNode(setting); // 取消当前正在编辑的节点 - - // 获取文档对象和body对象 - var doc = $(setting.treeObj.get(0).ownerDocument), - body = $(setting.treeObj.get(0).ownerDocument.body), curNode, tmpArrow, tmpTarget, - isOtherTree = false, // 标记是否为其他树 - targetSetting = setting, // 目标设置 - sourceSetting = setting, // 源设置 - preNode, nextNode, // 前一个节点和后一个节点 - preTmpTargetNodeId = null, // 临时目标节点ID - preTmpMoveType = null, // 临时移动类型 - tmpTargetNodeId = null, // 临时目标节点ID - moveType = consts.move.TYPE_INNER, // 移动类型,默认为内部移动 - mouseDownX = eventMouseDown.clientX, // 鼠标按下时的X坐标 - mouseDownY = eventMouseDown.clientY, // 鼠标按下时的Y坐标 - startTime = (new Date()).getTime(); // 记录开始时间 - - if (tools.uCanDo(setting)) { // 如果可以执行操作 - doc.bind("mousemove", _docMouseMove); // 绑定鼠标移动事件到文档上 - } - - function _docMouseMove(event) { - // 避免在点击节点后开始拖动 - if (root.dragFlag == 0 && Math.abs(mouseDownX - event.clientX) < setting.edit.drag.minMoveSize - && Math.abs(mouseDownY - event.clientY) < setting.edit.drag.minMoveSize) { - return true; // 如果鼠标移动距离小于最小拖动距离,则不进行拖动操作 - } - var i, l, tmpNode, tmpDom, tmpNodes; - body.css("cursor", "pointer"); // 将鼠标指针样式设置为指针 - - if (root.dragFlag == 0) { - // 检查是否允许拖动操作 - if (tools.apply(setting.callback.beforeDrag, [setting.treeId, nodes], true) == false) { - _docMouseUp(event); // 如果不允许拖动,则调用_docMouseUp方法结束拖动 - return true; // 返回true表示处理完成 - } - - // 遍历所有节点 - for (i = 0, l = nodes.length; i < l; i++) { - // 如果是第一个节点,初始化dragNodeShowBefore数组 - if (i == 0) { - root.dragNodeShowBefore = []; - } - // 获取当前节点 - tmpNode = nodes[i]; - // 如果当前节点是父节点且处于展开状态 - if (data.nodeIsParent(setting, tmpNode) && tmpNode.open) { - // 折叠该节点 - view.expandCollapseNode(setting, tmpNode, !tmpNode.open); - // 记录该节点在拖拽前的状态为展开 - root.dragNodeShowBefore[tmpNode.tId] = true; - } else { - // 记录该节点在拖拽前的状态为折叠 - root.dragNodeShowBefore[tmpNode.tId] = false; - } - } - - // 设置拖拽标志位为1 - root.dragFlag = 1; - // 隐藏悬停的DOM元素 - roots.showHoverDom = false; - // 显示iframe遮罩层 - tools.showIfameMask(setting, true); - - // 排序逻辑 - var isOrder = true, lastIndex = -1; - if (nodes.length > 1) { - // 获取父节点或根节点的子节点列表 - var pNodes = nodes[0].parentTId ? data.nodeChildren(setting, nodes[0].getParentNode()) : data.getNodes(setting); - tmpNodes = []; - // 遍历父节点或根节点的子节点列表 - for (i = 0, l = pNodes.length; i < l; i++) { - // 如果当前节点在dragNodeShowBefore中有记录 - if (root.dragNodeShowBefore[pNodes[i].tId] !== undefined) { - // 检查顺序是否被打乱 - if (isOrder && lastIndex > -1 && (lastIndex + 1) !== i) { - isOrder = false; - } - // 将当前节点添加到临时节点数组中 - tmpNodes.push(pNodes[i]); - // 更新最后一个索引值 - lastIndex = i; - } - // 如果临时节点数组的长度与原节点数组长度相同,则替换原节点数组并退出循环 - if (nodes.length === tmpNodes.length) { - nodes = tmpNodes; - break; - } - } - } - if (isOrder) { - // 获取第一个节点的前一个节点 - preNode = nodes[0].getPreNode(); - // 获取最后一个节点的下一个节点 - nextNode = nodes[nodes.length - 1].getNextNode(); - } - - // 创建一个新的