lowbase/jstree

jsTree是一个jQuery插件,提供交互式树。

维护者

详细信息

github.com/lowbase/jstree

主页

源代码

安装数: 3 191

依赖者: 1

推荐者: 0

安全: 0

星标: 0

关注者: 2

分支: 1 385

语言:JavaScript

类型:组件

3.3.0 2016-03-19 23:19 UTC

This package is not auto-updated.

Last update: 2024-09-20 18:54:13 UTC


README

jsTree是一个jQuery插件,提供交互式树。它是完全免费的,开源并且以MIT许可证分发。

jsTree易于扩展、主题化和配置,支持HTML & JSON数据源、AJAX & 异步回调加载。

jsTree在box-model(content-box或border-box)下都能正常工作,可以加载为AMD模块,并内置了用于响应式设计的移动主题,可以轻松自定义。它使用jQuery的事件系统,因此绑定树中各种事件的回调函数既熟悉又简单。

您还将获得

  • 拖放支持
  • 键盘导航
  • 行内编辑、创建和删除
  • 三态复选框
  • 模糊搜索
  • 可自定义节点类型

除了本README之外,您还可以在jstree.com & 讨论组上找到更多信息.

入门指南

包含所有必要的文件

要开始,您需要在页面上准备3样东西

  1. jQuery(任何高于1.9.1的版本都可以工作)
  2. jstree主题(默认提供了一个主题)
  3. jstree源代码文件
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.0.9/themes/default/style.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.0.9/jstree.min.js"></script>

如果您决定自行托管jstree,文件位于dist文件夹中。您可以安全地忽略dist/libs文件夹。

使用HTML填充树

现在我们已准备好创建树了,行内HTML是最简单的选项(适用于菜单)。您只需选择一个节点(使用jQuery选择器)并调用.jstree()函数,让jstree知道您想在所选节点内渲染树。$.jstree.create(element)也可以使用。

<div id="container">
  <ul>
    <li>Root node
      <ul>
        <li>Child node 1</li>
        <li>Child node 2</li>
      </ul>
    </li>
  </ul>
</div>
<script>
$(function() {
  $('#container').jstree();
});
</script>

查看结果

您可以在渲染节点时添加一些选项,使用data-attribute(注意引号)

<li data-jstree='{ "selected" : true, "opened" : true }'>Root node ...

使用数组(或JSON)填充树

从HTML构建树很容易,但不是很灵活,行内JS数据是一个更好的选择

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : [
        { "text" : "Root node", "children" : [
            { "text" : "Child node 1" },
            { "text" : "Child node 2" }
          ]
        }
      ]
    }
  });
});
</script>

查看结果

与先前的简单HTML示例不同,这次.jstree()函数接受一个配置对象。

目前重要的是要注意,jstree会尝试解析您在core.data键中指定的任何数据,并使用它来创建树。如前一个示例所示,如果此键不存在,jstree将尝试解析容器的行内HTML。

所需的JSON格式

您使用的数据必须符合特定格式,树中的每个分支由一个对象表示,该对象至少应包含一个 text 键。可以使用 children 键向分支添加子节点,它应该是一个对象数组。

请注意,如果您只需要具有特定文本的节点,可以使用简单的字符串代替对象,上面的数据可以写作:

[ { "text" : "Root node", "children" : [ "Child node 1", "Child node 2" ] } ]

每个节点还有其他可用的选项,只有需要时才设置它们,例如

  • id - 使节点以后可以被识别(也将用作 LI 节点的 DOM ID)。请确保在树实例中不要重复相同的 ID(这将违背其作为唯一标识符的目的,并可能导致 jstree 出现问题)。
  • icon - 用于节点图标的字符串,可以是文件的路径,也可以是类名(或类名列表),您可以在 CSS 中对其进行样式化(也适用于字体图标)。
  • data - 可以是任何您想要的内容 - 它是与节点相关联的元数据 - 您可以在以后访问和修改它 - 它对节点的视觉效果没有影响。
  • state - 一个对象,指定有关节点的几个选项
    • selected - 如果节点应该被初始选中
    • opened - 如果节点应该被初始展开
    • disabled - 如果节点应该被禁用
    • checked - 仅限复选框插件 - 如果节点应该被选中(仅当 tie_selectionfalse 时使用,您应该只在真正了解自己在做什么时才这样做)
    • undetermined - 仅限复选框插件 - 如果节点应该以不确定状态渲染(仅与延迟加载一起使用,并且节点尚未加载时使用,否则此状态将自动计算)。
  • type - 类型插件特定 - 节点的类型(应在类型配置中定义),如果未设置,则假定 "default"
  • li_attr - 将用于向结果 LI DOM 节点添加 HTML 属性的值对象。
  • a_attr - 将用于向结果 A 节点添加 HTML 属性的值对象。

这里有一个带有一些这些属性设置的新演示

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : [
          {
              "text" : "Root node",
              "state" : {"opened" : true },
              "children" : [
                  {
                    "text" : "Child node 1",
                    "state" : { "selected" : true },
                    "icon" : "glyphicon glyphicon-flash"
                  },
                  { "text" : "Child node 2", "state" : { "disabled" : true } }
              ]
        }
      ]
    }
  });
});
</script>

查看结果

使用AJAX填充树

基于前面的示例,让我们看看如何让 jstree 为您执行 AJAX 请求。

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : {
        "url" : "//www.jstree.com/fiddle/",
        "dataType" : "json" // needed only if you do not supply JSON headers
      }
    }
  });
});
</script>

服务器响应是

[{
  "id":1,"text":"Root node","children":[
    {"id":2,"text":"Child node 1"},
    {"id":3,"text":"Child node 2"}
  ]
}]

查看结果

您可以将 core.data 设置为 jQuery AJAX 配置。jstree 将访问该 URL,并且如果返回格式正确的 JSON,它将被显示。

如果您无法提供正确的 JSON 头部信息,请将 core.data.dataType 设置为 "json"

服务器响应中的 ID 可以使节点以后被识别(我们将在接下来的几个演示中看到),但它们不是必需的。

当使用 ID 时,请确保它们在特定树内部是唯一的

使用AJAX和懒加载节点填充树

延迟加载意味着节点将在需要时加载。想象一下,您想要显示大量节点,但使用单个请求加载它们会产生太多的流量。延迟加载可以使动态加载节点成为可能 - 当用户浏览树时,jstree 将执行 AJAX 请求。

这里我们使用我们之前的示例,并延迟加载 "Child node 1" 节点。

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : {
        "url" : "//www.jstree.com/fiddle/?lazy",
        "data" : function (node) {
          return { "id" : node.id };
        }
      }
    }
  });
});
</script>

初始服务器响应是

[{
  "id":1,"text":"Root node","children":[
    {"id":2,"text":"Child node 1","children":true},
    {"id":3,"text":"Child node 2"}
  ]
}]

查看结果

现在让我们关注一下有什么不同。首先,数据对象的 "data" 配置选项。如果您用 jQuery 检查,它应该是字符串或对象。但是 jstree 使您可以设置一个函数。

每次jstree需要发起AJAX调用时,此函数将被调用,并接收一个单一参数 - 正在加载的节点。此函数的返回值将用作AJAX调用的实际"data"。为了更好地理解,请打开演示并查看控制台中的请求。

您会发现第一个请求发往:http://www.jstree.com/fiddle?lazy&id=# #是当jstree需要加载根节点时,函数接收的特殊ID。

现在打开根节点 - 将显示两个子节点,但不会发起请求 - 这是因为我们已经在第一个请求中加载了这些子节点。

接下来是另一个区别 - "子节点1"看起来是关闭的 - 这是因为在我们提供的数据中,"children"属性被设置为true(您可以在服务器响应中看到它)。这个特殊值指示jstree需要延迟加载"子节点1"节点。

打开此节点 - 您将看到发起下一个请求到:http://www.jstree.com/fiddle?lazy&id=2 ID被设置为2,因为正在加载的节点的ID是2,并且我们已经配置jstree在AJAX请求中发送节点ID(通过data函数)。

服务器响应是

["Child node 3","Child node 4"]

您还可以将"url"设置为一个函数,它的工作方式与"data"相同 - 每次需要发起请求时,jstree都会调用您的函数,请求将发送到您在此函数中返回的内容。当处理类似http://example.com/get_children/1的URL时,这非常有用。

使用回调函数填充树

有时您可能不希望jsTree为您发起AJAX调用 - 您可能想自己发起它们,或使用其他方法来填充树。在这种情况下,您可以使用回调函数。

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : function (node, cb) {
        if(node.id === "#") {
          cb([{"text" : "Root", "id" : "1", "children" : true}]);
        }
        else {
          cb(["Child"]);
        }
      }
    }
  });
});
</script>

查看结果

如您所见,您的函数将接收两个参数 - 需要加载子节点的节点以及一个回调函数,当您得到数据时调用该回调函数。数据遵循相同的熟悉的JSON格式,延迟加载与AJAX的工作方式相同(如上例所示)。

处理事件

jstree提供了许多事件来让您知道树发生了什么。事件与您如何填充树无关。让我们使用最基本的事件changed - 它在树的选定更改时触发。

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : [
        {"id" : 1, "text" : "Node 1"},
        {"id" : 2, "text" : "Node 2"},
      ]
    }
  });
  $('#container').on("changed.jstree", function (e, data) {
    console.log("The selected nodes are:");
    console.log(data.selected);
  });
});
</script>

查看结果

所有jstree事件都在特殊的"$.jstree"命名空间中触发 - 这也是为什么我们监听"changed.jstree"。处理程序本身接收一个额外的参数 - 它将包含关于发生的所有您需要了解的事件信息。在这种情况下,data.selected是选定节点ID的数组(请注意,如果您没有指定ID,它们将自动生成)。

让我们扩展一下,并记录出节点的文本而不是ID。

$('#container').on("changed.jstree", function (e, data) {
  console.log(data.instance.get_selected(true)[0].text);
  console.log(data.instance.get_node(data.selected[0]).text);
});

上面的两行代码达到完全相同的效果 - 获取第一个选定节点的文本。

data参数对象中,您总是会得到一个instance键 - 这是树实例的引用,因此您可以轻松调用方法。

所有可用函数和事件均在API文档中进行了说明。

使用API与树交互

在先前的例子中,我们只是触及了与树交互的表面。让我们继续获取实例并在该实例上调用方法。

<button>Select node 1</button>
<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : [
        {"id" : 1, "text" : "Node 1"},
        {"id" : 2, "text" : "Node 2"},
      ]
    }
  });
  $('button').on("click", function () {
    var instance = $('#container').jstree(true);
    instance.deselect_all();
    instance.select_node('1');
  });
});
</script>

查看结果

上面的例子展示了如何获取jstree实例的引用(再次使用选择器,但这次我们传递一个布尔值true),并调用一些方法 - 最后一个方法是按ID选择节点。

方法也可以这样调用

$('#container').jstree("select_node", "1");

所有可用函数和事件均在API文档中进行了说明。

更多配置信息

我们已经就配置对象进行了概述(当我们在指定内联和AJAX数据源时)。

$("#tree").jstree({ /* config object goes here */ });

配置对象中的每个键对应一个插件,该键的值是该插件的配置。还有两个特殊键"core""plugins"

  • "core"存储核心配置选项。
  • "plugins"是一个包含您希望在实例中激活的插件名称(字符串)的数组。

配置时,您只需设置与默认值不同的值。

所有配置选项和默认值均在API文档中进行了记录。

$("#tree").jstree({
  "core" : { // core options go here
    "multiple" : false, // no multiselection
    "themes" : {
      "dots" : false // no connecting dots between dots
    }
  },
  "plugins" : ["state"] // activate the state plugin on this instance
});

查看结果

我们将进一步介绍所有插件。

请注意,默认情况下,所有对结构的修改都被阻止 - 这意味着拖放、创建、重命名、删除将不会工作,除非您启用它们。

$("#tree").jstree({
  "core" : {
    "check_callback" : true, // enable all modifications
  },
  "plugins" : ["dnd","contextmenu"]
});

查看结果

"core.check_callback"也可以设置为函数,该函数将在每次即将发生修改时调用(或者当jstree需要检查是否可以修改时)。如果您返回true,则允许操作,false的值表示不允许。您可以期望的操作包括create_noderename_nodedelete_nodemove_nodecopy_nodemore参数将包含调用检查的插件提供的信息。例如,DND插件将提供一个包含正在检查的移动或复制操作信息的对象 - 是否是多树操作,当前悬停的节点是哪个,插入箭头指向哪里 - 在之前、之后或内部等。

$("#tree").jstree({
  "core" : {
    "check_callback" : function (operation, node, parent, position, more) {
      if(operation === "copy_node" || operation === "move_node") {
        if(parent.id === "#") {
          return false; // prevent moving a child above or below the root
        }
      },
      return true; // allow everything else
    }
  },
  "plugins" : ["dnd","contextmenu"]
});

查看结果

您收到的more参数包含与正在执行的检查相关的其他信息。

例如:在用户拖动节点时,move_nodecopy_node检查将重复触发,如果检查由dnd插件触发,则more将包含一个dnd键,并将其设置为true。您可以通过检查more.dnd,并且只有当dnd触发了检查时才执行某些操作。如果您只想在节点真正即将被放下时执行操作,则检查more.core

插件

jsTree附带了一些捆绑的插件,但它们只会修改您的树,如果您使用"plugins"配置选项激活它们。以下是每个插件的简要说明。您可以在API文档中了解有关每个插件的可用配置选项的更多信息。

checkbox

在节点前渲染一个复选框图标,使多选变得容易。它还有一个“三态”选项,这意味着某些子节点被选中时,节点将获得一个“方块”图标。

请注意,如果启用了任何类型的级联,禁用节点也可能被选中(不是它们自己,例如,当禁用节点的父节点被选中且选择配置为级联向下时)。

$("#tree").jstree({
  "plugins" : ["checkbox"]
});

查看结果

contextmenu

使您能够在节点上右键单击并显示一个包含可配置操作的菜单。

$("#tree").jstree({
  "core" : { "check_callback" : true }, // so that modifying operations work
  "plugins" : ["contextmenu"]
});

查看结果

dnd

使您能够拖放树节点并重新排列树。

$("#tree").jstree({
  "core" : { "check_callback" : true }, // so that operations work
  "plugins" : ["dnd"]
});

查看结果

massload

使您能够一次加载多个节点(对于懒加载的树)。

$("#tree").jstree({
  "core" : {
    "data" : { .. AJAX config .. }
  },
  "massload" : {
    "url" : "/some/path",
    "data" : function (nodes) {
      return { "ids" : nodes.join(",") };
    }
  },
  "plugins" : [ "massload", "state" ]
});

search

添加了在树中搜索项并仅显示匹配节点的可能性。它还包含AJAX / 回调钩子,因此搜索也可以在懒加载的树中工作。

<form id="s">
  <input type="search" id="q" />
  <button type="submit">Search</button>
</form>
<script>
$("#container").jstree({
  "plugins" : ["search"]
});
$("#s").submit(function(e) {
  e.preventDefault();
  $("#container").jstree(true).search($("#q").val());
});
</script>

查看结果

sort

根据比较配置选项函数自动排列所有同级节点,默认为字母顺序。

$("#tree").jstree({
  "plugins" : ["sort"]
});

查看结果

state

将所有打开和选择的节点保存在用户的浏览器中,因此当返回到同一树时,将恢复之前的状态。

$("#tree").jstree({
  // the key is important if you have multiple trees in the same domain
  "state" : { "key" : "state_demo" },
  "plugins" : ["state"]
});

查看结果

types

使您能够为节点添加“类型”,这意味着可以轻松控制节点组的嵌套规则和图标,而不是单独控制。要设置节点类型,请将类型属性添加到节点结构中。

$("#tree").jstree({
  "types" : {
    "default" : {
      "icon" : "glyphicon glyphicon-flash"
    },
    "demo" : {
      "icon" : "glyphicon glyphicon-ok"
    }
  },
  "plugins" : ["types"]
});

查看结果

unique

强制规定不允许存在同名节点作为同级节点 - 防止将节点重命名和移动到已包含同名节点的父节点。

$("#tree").jstree({
  "plugins" : ["unique"]
});

查看结果

wholerow

使每个节点呈现块级样式,从而使选择更加容易。在旧浏览器中,对于大型树可能导致性能下降。

$("#tree").jstree({
  "plugins" : ["wholerow"]
});

查看结果

更多插件

如果您创建了自己的插件(或下载第三方插件),必须在页面上包含其源代码,并在"plugins"配置数组中列出其名称。

// conditional select
(function ($, undefined) {
  "use strict";
  $.jstree.defaults.conditionalselect = function () { return true; };
  $.jstree.plugins.conditionalselect = function (options, parent) {
    this.activate_node = function (obj, e) {
      if(this.settings.conditionalselect.call(this, this.get_node(obj))) {
        parent.activate_node.call(this, obj, e);
      }
    };
  };
})(jQuery);
$("#tree").jstree({
  "conditionalselect" : function (node) {
    return node.text === "Root node" ? false : true;
  },
  "plugins" : ["conditionalselect"]
});

查看结果

如这里所见,在创建插件时,您可以定义默认配置,向jstree添加自己的函数,或覆盖现有函数,同时保持调用被覆盖函数的能力。

许可证 & 贡献

请勿编辑“dist”子目录中的文件,因为它们是通过grunt生成的。您将在“src”子目录中找到源代码!

如果您愿意,您可以随时[捐赠一小笔金额][paypal],以帮助jstree的开发。[paypal]: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal@vakata.com&currency_code=USD&amount=&return=http://jstree.com/donation&item_name=Buy+me+a+coffee+for+jsTree

版权所有 (c) 2014 Ivan Bozhanov (http://vakata.com)

许可协议为MIT许可协议