7

今天早上我遇到了优秀的 jstree jQuery UI 插件。一句话—​​—太棒了!它易于使用,易于设计,并且可以按照包装盒上的说明进行操作。我还没有弄清楚的一件事是 - 在我的应用程序中,我想确保在任何给定时间只扩展一个节点。即当用户单击+ 按钮并展开一个节点时,任何先前展开的节点都应该被静默折叠。我需要这样做的部分原因是为了防止容器 div 的一个相当长的树视图在溢出时创建一个丑陋的滚动条,同时也为了避免用户的“选择过载”。

我想有一些方法可以做到这一点,但是好的但相当简洁的 jstree 文档并没有帮助我确定正确的方法来做到这一点。我将不胜感激任何帮助。

4

4 回答 4

5

jsTree 很棒,但它的文档相当密集。我最终想通了,所以这里是任何遇到这个线程的人的解决方案。

首先,您需要将 open_node 事件绑定到相关树。类似的东西

$("tree").jstree({"themes":objTheme,"plugins":arrPlugins,"core":objCore}).
bind("open_node.jstree",function(event,data){closeOld(data)}); 

即您配置treeview 实例,然后绑定open_node 事件。在这里,我调用 closeOld 函数来完成我需要的工作 - 关闭任何其他可能打开的节点。功能是这样的

function closeOld(data)
{
    var nn = data.rslt.obj;
    var thisLvl = nn;
    var levels = new Array();
    var iex = 0;
    while (-1 != thisLvl)
    {
        levels.push(thisLvl);
        thisLvl = data.inst._get_parent(thisLvl);
        iex++;
    }

    if (0 < ignoreExp)
    {
        ignoreExp--;
        return;
    }

    $("#divElements").jstree("close_all");
    ignoreExp = iex;
    var len = levels.length - 1;
    for (var i=len;i >=0;i--) $('#divElements').jstree('open_node',levels[i]);
}

这将正确处理所有其他节点的折叠,而与刚刚展开的节点的嵌套级别无关。

所涉及步骤的简要说明

  • 首先,我们后退树视图,直到我们到达顶级节点(jstree 中的 -1),确保我们在数组级别中记录进程中遇到的每个祖先节点
  • 接下来我们折叠树视图中的所有节点
  • 我们现在将重新展开级别数组中的所有节点。在这样做的同时,我们不希望这段代码再次执行。为了阻止这种情况发生,我们将全局ignoreEx变量设置为级别中的节点数
  • 最后,我们逐步遍历关卡中的节点并展开每个节点
于 2012-08-28T12:33:09.187 回答
2

上面的答案将一次又一次地构建树。下面的代码将打开已经打开的节点并折叠,它不会再次构造树。

.bind("open_node.jstree",function(event,data){
        closeOld(data);
        });

并且 closeOld 函数包含:

function closeOld(data)
{
    if($.inArray(data.node.id, myArray)==-1){
            myArray.push(data.node.id);
            if(myArray.length!=1){
                var arr =data.node.id+","+data.node.parents;
                var res = arr.split(",");
                var parentArray = new Array();
                var len = myArray.length-1;
                for (i = 0; i < res.length; i++) {
                    parentArray.push(res[i]);
                }
                for (var i=len;i >=0;i--){
                    var index = $.inArray(myArray[i], parentArray);
                if(index==-1){
                    if(data.node.id!=myArray[i]){
                    $('#jstree').jstree('close_node',myArray[i]);
                        delete myArray[i];
                    }
                }
                }
        }
    }
于 2015-04-03T12:28:09.593 回答
1

我通过使用事件“before_open”并关闭所有节点来实现这一点,我的树只有一层,不确定这是否是你需要的。

$('#dtree').on('before_open.jstree', function(e, data){
    $("#dtree").jstree("close_all");
});
于 2018-02-28T19:52:16.623 回答
1

jstree 3.3.2 的另一个例子。它使用下划线库,可以随意调整解决方案以适应 jquery 或 vanillla js。

$(function () {
    var tree = $('#tree');
    tree.on('before_open.jstree', function (e, data) {
        var remained_ids = _.union(data.node.id, data.node.parents);
        var $tree = $(this);
        _.each(
                $tree
                    .jstree()
                    .get_json($tree, {flat: true}),
                function (n) {
                    if (
                        n.state.opened &&
                        _.indexOf(remained_ids, n.id) == -1
                    ) {
                        grid.jstree('close_node', n.id);
                    }
                }
        );
    });
    tree.jstree();
});
于 2016-10-20T03:02:44.430 回答