09.07 页面刷新后,如何保持节点展开状态 —— zTree 进阶

原创
2022/05/10 21:28
阅读数 1.2K

简介

虽然 Ajax 的大量应用已经让很多网页不会为了刷新数据而去刷新页面,但还是有不少朋友的项目中遇到必须要刷新页面的情况,同时还要保持 树节点 展开状态的需求,这里专门对此问题进行分析。

思路

  1. 页面刷新之前把展开的节点 id 统计出来,保存到 cookie 或 webstorage 内,具体选择哪种,看你自己的需求
  2. 每次页面加载后,都从保存的地方把之前已展开的节点 id 取出
  3. 把节点数据中对应的节点设置 open = true
  4. 让 zTree 初始化

补充:

其实你也可以在 zTree 初始化以后, 逐一根据 节点id 去让节点展开,但是这样效率不高,我不提倡。 不过如果你是异步加载的话,那也只能这样操作了。

js 代码

初始化参数 & 节点数据

var setting = {
    data: {
        simpleData: {
            enable: true
        }
    }
};
 
var zNodes = [
    {id: 1, pId: 0, name: "父节点1 - 展开"},
    {id: 11, pId: 1, name: "父节点11 - 折叠"},
    {id: 111, pId: 11, name: "叶子节点111"},
    {id: 112, pId: 11, name: "叶子节点112"},
    {id: 113, pId: 11, name: "叶子节点113"},
    {id: 114, pId: 11, name: "叶子节点114"},
    {id: 12, pId: 1, name: "父节点12 - 折叠"},
    {id: 121, pId: 12, name: "叶子节点121"},
    {id: 122, pId: 12, name: "叶子节点122"},
    {id: 123, pId: 12, name: "叶子节点123"},
    {id: 124, pId: 12, name: "叶子节点124"},
    {id: 13, pId: 1, name: "父节点13 - 没有子节点", isParent: true},
    {id: 2, pId: 0, name: "父节点2 - 折叠"},
    {id: 21, pId: 2, name: "父节点21 - 展开"},
    {id: 211, pId: 21, name: "叶子节点211"},
    {id: 212, pId: 21, name: "叶子节点212"},
    {id: 213, pId: 21, name: "叶子节点213"},
    {id: 214, pId: 21, name: "叶子节点214"},
    {id: 22, pId: 2, name: "父节点22 - 折叠"},
    {id: 221, pId: 22, name: "叶子节点221"},
    {id: 222, pId: 22, name: "叶子节点222"},
    {id: 223, pId: 22, name: "叶子节点223"},
    {id: 224, pId: 22, name: "叶子节点224"},
    {id: 23, pId: 2, name: "父节点23 - 折叠"},
    {id: 231, pId: 23, name: "叶子节点231"},
    {id: 232, pId: 23, name: "叶子节点232"},
    {id: 233, pId: 23, name: "叶子节点233"},
    {id: 234, pId: 23, name: "叶子节点234"},
    {id: 3, pId: 0, name: "父节点3 - 没有子节点", isParent: true}
];
 
var zTreeObj;
$(document).ready(function () {
    // 绑定事件,用于捕获页面 关闭 / 刷新 前的事件
    window.onbeforeunload = beforeUnload;
    onLoad();
});

onLoad()

页面加载后执行,用于初始化

function onLoad() {
    // 获取 cookie 中的上一次展开的节点 id 数据
    var lastOpenStr = getCookie('last_open') || '',
        lastOpen = lastOpenStr.split(',');
 
    var tmp = {}, i, j, node;
    // 根据历史数据生成一个 map 便于后面判断
    for (i = 0, j = lastOpen.length; i < j; i++) {
        tmp[lastOpen[i]] = 1;
    }
    // 遍历节点数据,设置 open 属性
    for (i = 0, j = zNodes.length; i < j; i++) {
        node = zNodes[i];
        if (tmp[node.id]) {
            node.open = true;
        }
    }
    // 初始化 zTree    
    zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
}

beforeUnload()

页面关闭前,保存当前已展开的节点 id

function beforeUnload() {
    var openList = [],
        nodes = zTreeObj.getNodesByParam('open', true),
        i, j;
    for (i = 0, j = nodes.length; i < j; i++) {
        openList.push(nodes[i].id);
    }
    // 将 id 集合保存到 cookie 内
    setCookie('last_open', openList.join(','));
}

setCookie & getCookie

这是两个简单的工具方法,仅仅用于 Demo 演示,实际使用中,建议你使用标准的控件 或更完善的写法,便于控制 cookie 的 domain 以及 有效期

function setCookie(name, value) {
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
    document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + exp.toGMTString();
}
function getCookie(name) {
    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
        return decodeURIComponent(arr[2]);
    } else {
        return null;
    }
}

其实这个并不难,拿去放到你的项目里,尝试一下吧!

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
1 评论
0 收藏
0
分享
返回顶部
顶部