强大的动态树插件与jQuery - jsTree

南宫炜
2023-12-01

jsTree是一个功能强大的jQuery插件,用于生成动态的交互式树视图(例如文件夹树),支持内联编辑,拖放,复选框,键盘导航等。

>>>演示    >>>下载

更多功能:

  • 支持HTML和JSON数据。
  • 启用AJAX。
  • 自定义节点图标。
  • 延迟加载。
  • 回调函数。
  • 可搜索和可过滤。

基本用法:

 1.安装和下载。

# NPM
$ npm install jstree --save

2.在文档中导入您选择的主题CSS。

<link rel="stylesheet" href="themes/default/style.min.css">
<link rel="stylesheet" href="themes/default-dark/style.min.css">

3.将jQuery库和jsTree插件的脚本导入到文档中。

<script src="https://code.jquery.com/jquery-1.12.4.min.js" 
        integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" 
        crossorigin="anonymous"></script>
<script src="jstree.min.js"></script>

4.从HTML数据生成树结构。

<div id="html" class="demo">
  <ul>
    <li data-jstree='{ "opened" : true }'>Root node
      <ul>
        <li data-jstree='{ "selected" : true }'>Child node 1</li>
        <li>Child node 2</li>
      </ul>
    </li>
  </ul>
</div>

5.从内联数据生成树结构。

<div id="data" class="demo"></div>

6.通过AJAX从外部JSON文件生成树结构。

$('#ajax').jstree({
  'core' : {
    'data' : {
      "url" : "./root.json",
      "dataType" : "json" // needed only if you do not supply JSON headers
    }
  }
});

7.所有默认配置选项。

/**
 * data configuration
 *
 * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items).
 *
 * You can also pass in a HTML string or a JSON array here.
 *
 * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree.
 * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used.
 *
 * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result.
 *
 * __Examples__
 *
 *  // AJAX
 *  $('#tree').jstree({
 *    'core' : {
 *      'data' : {
 *        'url' : '/get/children/',
 *        'data' : function (node) {
 *          return { 'id' : node.id };
 *        }
 *      }
 *    });
 *
 *  // direct data
 *  $('#tree').jstree({
 *    'core' : {
 *      'data' : [
 *        'Simple root node',
 *        {
 *          'id' : 'node_2',
 *          'text' : 'Root node with options',
 *          'state' : { 'opened' : true, 'selected' : true },
 *          'children' : [ { 'text' : 'Child 1' }, 'Child 2']
 *        }
 *      ]
 *    }
 *  });
 *
 *  // function
 *  $('#tree').jstree({
 *    'core' : {
 *      'data' : function (obj, callback) {
 *        callback.call(this, ['Root 1', 'Root 2']);
 *      }
 *    });
 *
 * @name $.jstree.defaults.core.data
 */
data      : false,

/**
 * configure the various strings used throughout the tree
 *
 * You can use an object where the key is the string you need to replace and the value is your replacement.
 * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement.
 * If left as `false` no replacement is made.
 *
 * __Examples__
 *
 *  $('#tree').jstree({
 *    'core' : {
 *      'strings' : {
 *        'Loading ...' : 'Please wait ...'
 *      }
 *    }
 *  });
 *
 * @name $.jstree.defaults.core.strings
 */
strings     : false,

/**
 * determines what happens when a user tries to modify the structure of the tree
 * If left as `false` all operations like create, rename, delete, move or copy are prevented.
 * You can set this to `true` to allow all interactions or use a function to have better control.
 *
 * __Examples__
 *
 *  $('#tree').jstree({
 *    'core' : {
 *      'check_callback' : function (operation, node, node_parent, node_position, more) {
 *        // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node', 'copy_node' or 'edit'
 *        // in case of 'rename_node' node_position is filled with the new node name
 *        return operation === 'rename_node' ? true : false;
 *      }
 *    }
 *  });
 *
 * @name $.jstree.defaults.core.check_callback
 */
check_callback  : false,

/**
 * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc)
 * @name $.jstree.defaults.core.error
 */
error     : $.noop,

/**
 * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`)
 * @name $.jstree.defaults.core.animation
 */
animation   : 200,

/**
 * a boolean indicating if multiple nodes can be selected
 * @name $.jstree.defaults.core.multiple
 */
multiple    : true,

/**
 * theme configuration object
 * @name $.jstree.defaults.core.themes
 */
themes      : {
  /**
   * the name of the theme to use (if left as `false` the default theme is used)
   * @name $.jstree.defaults.core.themes.name
   */
  name      : false,

  /**
   * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme.
   * @name $.jstree.defaults.core.themes.url
   */
  url       : false,

  /**
   * the location of all jstree themes - only used if `url` is set to `true`
   * @name $.jstree.defaults.core.themes.dir
   */
  dir       : false,

  /**
   * a boolean indicating if connecting dots are shown
   * @name $.jstree.defaults.core.themes.dots
   */
  dots      : true,

  /**
   * a boolean indicating if node icons are shown
   * @name $.jstree.defaults.core.themes.icons
   */
  icons     : true,

  /**
   * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container
   * @name $.jstree.defaults.core.themes.ellipsis
   */
  ellipsis    : false,


  /**
   * a boolean indicating if the tree background is striped
   * @name $.jstree.defaults.core.themes.stripes
   */
  stripes     : false,

  /**
   * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants)
   * @name $.jstree.defaults.core.themes.variant
   */
  variant     : false,

  /**
   * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`.
   * @name $.jstree.defaults.core.themes.responsive
   */
  responsive    : false
},

/**
 * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user)
 * @name $.jstree.defaults.core.expand_selected_onload
 */
expand_selected_onload : true,

/**
 * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true`
 * @name $.jstree.defaults.core.worker
 */
worker : true,

/**
 * Force node text to plain text (and escape HTML). Defaults to `false`
 * @name $.jstree.defaults.core.force_text
 */
force_text : false,

/**
 * Should the node should be toggled if the text is double clicked . Defaults to `true`
 * @name $.jstree.defaults.core.dblclick_toggle
 */
dblclick_toggle : true,

/**
 * Should the loaded nodes be part of the state. Defaults to `false`
 * @name $.jstree.defaults.core.loaded_state
 */
loaded_state : false,

/**
 * Should the last active node be focused when the tree container is blurred and the focused again. This helps working with screen readers. Defaults to `true`
 * @name $.jstree.defaults.core.restore_focus
 */
restore_focus : true,

/**
 * Default keyboard shortcuts (an object where each key is the button name or combo - like 'enter', 'ctrl-space', 'p', etc and the value is the function to execute in the instance's scope)
 * @name $.jstree.defaults.core.keyboard
 */
keyboard : {
  'ctrl-space': function (e) {
    // aria defines space only with Ctrl
    e.type = "click";
    $(e.currentTarget).trigger(e);
  },

  'enter': function (e) {
    // enter
    e.type = "click";
    $(e.currentTarget).trigger(e);
  },

  'left': function (e) {
    // left
    e.preventDefault();
    if(this.is_open(e.currentTarget)) {
      this.close_node(e.currentTarget);
    }
    else {
      var o = this.get_parent(e.currentTarget);
      if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); }
    }
  },

  'up': function (e) {
    // up
    e.preventDefault();
    var o = this.get_prev_dom(e.currentTarget);
    if(o && o.length) { o.children('.jstree-anchor').focus(); }
  },

  'right': function (e) {
    // right
    e.preventDefault();
    if(this.is_closed(e.currentTarget)) {
      this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); });
    }
    else if (this.is_open(e.currentTarget)) {
      var o = this.get_node(e.currentTarget, true).children('.jstree-children')[0];
      if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); }
    }
  },

  'down': function (e) {
    // down
    e.preventDefault();
    var o = this.get_next_dom(e.currentTarget);
    if(o && o.length) { o.children('.jstree-anchor').focus(); }
  },

  '*': function (e) {
    // aria defines * on numpad as open_all - not very common
    this.open_all();
  },

  'home': function (e) {
    // home
    e.preventDefault();
    var o = this._firstChild(this.get_container_ul()[0]);
    if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); }
  },

  'end': function (e) {
    // end
    e.preventDefault();
    this.element.find('.jstree-anchor').filter(':visible').last().focus();
  },
  
  'f2': function (e) {
    // f2 - safe to include - if check_callback is false it will fail
    e.preventDefault();
    this.edit(e.currentTarget);
  }
}

更新日志:

2018年7月8日

  • v3.3.5:改进了html5 drags

2018年1月9日

  • 固定边缘情况,上下文菜单出现在错误的位置
 类似资料: