diff --git a/demo/cn/index.html b/demo/cn/index.html index 98f39ece4bc3dab2c027b3a81c14cb33318d1d22..9764e0b9372c06d9a9dec75aea2d61ef560da6cf 100644 --- a/demo/cn/index.html +++ b/demo/cn/index.html @@ -123,6 +123,7 @@ {id: 508, pId: 5, name: "右键菜单 的 实现", file: "super/rightClickMenu"}, {id: 511, pId: 5, name: "与其他 DOM 拖拽互动", file: "super/dragWithOther"}, {id: 512, pId: 5, name: "异步加载模式下全部展开", file: "super/asyncForAll"}, + {id: 517, pId: 5, name: "设置快捷键", file: "super/keyboard_navigation"}, {id: 6, pId: 0, name: "其他扩展功能 演示", open: false}, {id: 601, pId: 6, name: "隐藏普通节点", file: "exhide/common"}, diff --git a/demo/cn/super/fuzzySearch.html b/demo/cn/super/fuzzySearch.html index aac48cb9d7681d510c22828fe505ebc4bcf61077..afd6eb22f7df6e1ddb9bf355cb319cceb12c6d60 100644 --- a/demo/cn/super/fuzzySearch.html +++ b/demo/cn/super/fuzzySearch.html @@ -51,7 +51,7 @@

根据关键字模糊查找节点

-
[ 文件路径: fuzzySearch/fuzzySearch.html ]
+
[ 文件路径: super/fuzzySearch.html ]
diff --git a/demo/cn/super/keyboard_navigation.html b/demo/cn/super/keyboard_navigation.html new file mode 100644 index 0000000000000000000000000000000000000000..d65a22eba708337788073bbad3b87b1d0ea02b12 --- /dev/null +++ b/demo/cn/super/keyboard_navigation.html @@ -0,0 +1,102 @@ + + + + ZTREE DEMO - Keyboard navigation + + + + + + + + + + + + +

设置快捷键

+
[ 文件路径: super/keyboard_navigation.html ]
+
+
+
    +
    +
    +
      +
    • 1、设置说明

      +
        +
      • 键盘导航不需要特殊配置。
      • +
      • 只需要加载 keyboard_navigation.js 文件并初始化。
      • +
      +
    • +
    • 2、快捷键说明

      +
        +
      • Home (keycode 36):定位到第一个根节点
      • +
      • End (keycode 35):定位到树上最后一个节点
      • +
      • 下 (keycode 39):定位到下一个同级节点
      • +
      • 右 (keycode 40):定位到下一个可视节点(包括子节点/同级节点 以及后面的父级节点)
      • +
      • 上 (keycode 37):定位到前一个同级节点
      • +
      • 左 (keycode 38):定位到前一个可视节点(包括子节点/同级节点 以及后面的父级节点)
      • +
      • 空格 (keycode 32):切换当前父节点 折叠、展开状态
      • +
      +
    • +
    +
    +
    + + \ No newline at end of file diff --git a/demo/en/index.html b/demo/en/index.html index b25a9ea101bedb7771108f9be2f481e31e652b03..4e75c23b9a355c83d765c2e2f9bdc3dfe840ec94 100644 --- a/demo/en/index.html +++ b/demo/en/index.html @@ -123,6 +123,7 @@ {id: 508, pId: 5, name: "Right-click Menu", file: "super/rightClickMenu"}, {id: 511, pId: 5, name: "Drag With Other DOMs", file: "super/dragWithOther"}, {id: 512, pId: 5, name: "Expand All Nodes with Async", file: "super/asyncForAll"}, + {id: 517, pId: 5, name: "Keyboard Navigation", file: "super/keyboard_navigation"}, {id: 6, pId: 0, name: "Other Extension Package", open: false}, {id: 601, pId: 6, name: "hide ordinary node", file: "exhide/common"}, diff --git a/demo/en/super/fuzzySearch.html b/demo/en/super/fuzzySearch.html index 14b3a623b59d37d08d549f64ba6c3509e51cc169..34d5e1030f859ddf481fb8594a2f805065ebbd55 100644 --- a/demo/en/super/fuzzySearch.html +++ b/demo/en/super/fuzzySearch.html @@ -51,7 +51,7 @@

    Fuzzy Search

    -
    [ File Path: fuzzySearch/fuzzySearch.html ]
    +
    [ File Path: super/fuzzySearch.html ]
      diff --git a/demo/en/super/keyboard_navigation.html b/demo/en/super/keyboard_navigation.html new file mode 100644 index 0000000000000000000000000000000000000000..8d11b125cd46a660ab905194269deddf38ec8fb0 --- /dev/null +++ b/demo/en/super/keyboard_navigation.html @@ -0,0 +1,102 @@ + + + + ZTREE DEMO - Keyboard navigation + + + + + + + + + + + + +

      Keyboard navigation

      +
      [ File Path: super/keyboard_navigation.html ]
      +
      +
      +
        +
        +
        +
          +
        • 1. Explanation of setting

          +
            +
          • Keyboard navigation does not require special configuration setting.
          • +
          • It does require that the keyboard_navigation.js file is loaded and the function initialized.
          • +
          +
        • +
        • 2. Explanation of navigation

          +
            +
          • Home: home key (keycode 36) Goes to the first root element is visible
          • +
          • End: end key (keycode 35) Goes to the last leaf node and will expand nodes and scroll the element into view
          • +
          • Down: right cursor key (keycode 39) Goes to the next visible node in the tree following the hierarchy
          • +
          • Next: down cursor key (keycode 40) Goes to the next visible node at the same level
          • +
          • Up: up cursor key (keycode 37) Goes to the prior visible node at the same level
          • +
          • Previous: left cursor key (keycode 38) Goes to the prior visible node following the hierarchy
          • +
          • Toggle: space key (keycode 32) Toggles the expand/collapse state of a parent node
          • +
          +
        • +
        +
        +
        + + \ No newline at end of file diff --git a/demo/js/keyboard_navigation.js b/demo/js/keyboard_navigation.js new file mode 100644 index 0000000000000000000000000000000000000000..11f5e05c249366bfb2c66fcdec3cbe5ec810c8b1 --- /dev/null +++ b/demo/js/keyboard_navigation.js @@ -0,0 +1,255 @@ +/* + * JQuery zTree keyboard navigation extension + * zTree v3.5.42 or later + * http://www.xbrlquery.com/ + * + * Copyright (c) 2019 Bill Seddon + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * Date: 2020-02-18 + */ + +( function ($) +{ + /** + * Creates a function that adds keyboard navigation: + * Home: home key (keycode 36) Goes to the first root element is visible + * End: end key (keycode 35) Goes to the last leaf node and will expand nodes and scroll the element into view + * Down: right cursor key (keycode 39) Goes to the next visible node in the tree following the hierarchy + * Next: down cursor key (keycode 40) Goes to the next visible node at the same level + * Up: up cursor key (keycode 37) Goes to the prior visible node at the same level + * Previous: left cursor key (keycode 38) Goes to the prior visible node following the hierarchy + * Toggle: space key (keycode 32) Toggles the expand/collapse state of a parent node + */ + $.fn.zTreeKeyboardNavigation = function(zTree, element) + { + if (typeof element === 'string' || element instanceof String) + { + element = $(element); + } + + var rootNodes = zTree.getNodes(); + if ( ! rootNodes ) return; + + var focusSelectedNode = function() + { + if( ( selectedNodes = zTree.getSelectedNodes() ) && selectedNodes.length ) + { + $("#" + selectedNodes[0].tId ).focus(); + } + } + + $(element).bind( 'keydown', function( e ) + { + var selectedNodes = zTree.getSelectedNodes(); + var selectedNode = selectedNodes.length ? selectedNodes[0] : null; + + var processSpace = function() + { + // If there are no nodes or the selected node is not a parent, get out + if ( selectedNode && selectedNode.isParent ) + { + // Toggle the node + zTree.expandNode( selectedNode, null, null, null, false ); + } + } + + var processHome = function() + { + zTree.selectNode( rootNodes[0], false, true ); + } + + var processEnd = function() + { + var nodes = zTree.transformToArray(rootNodes); + // Select the last node + zTree.selectNode( nodes[ nodes.length - 1 ] ); + } + + var processUp = function() + { + var priorNode; + if ( selectedNode ) + { + priorNode = selectedNode.getPreNode(); + if ( ! priorNode ) return; + } + else + { + processEnd(); + } + + if ( ! priorNode ) return; + + zTree.selectNode( priorNode ); + } + + var processDown = function() + { + var nextNode; + if ( selectedNode ) + { + nextNode = selectedNode.getNextNode(); + if ( ! nextNode ) return; + } + else + { + processHome(); + } + + if ( ! nextNode ) return; + + zTree.selectNode( nextNode ); + } + + var processOut = function() + { + if ( ! selectedNode ) return; + + var parentNode = selectedNode.getParentNode(); + var priorNode = selectedNode.getPreNode(); + if ( ! parentNode && ! priorNode ) return; // Must have been the root node + + if ( priorNode ) + { + if ( priorNode.isParent ) + { + // There is a prior node, now the the question is where is the last open node? + while ( priorNode ) + { + if ( ! priorNode.isParent || ! priorNode.open || ! priorNode.children ) break; + + priorNode = priorNode.children[ priorNode.children.length -1 ]; + } + + zTree.selectNode( priorNode ); + return; + } + else + { + zTree.selectNode( priorNode ); + return; + } + } + + // Find the parent node with a valid prior sibling + if ( parentNode ) + { + // This call should be silent otherwise (in my view a bug in) + // selectNode causes the root node to blur + zTree.selectNode( parentNode, false, true ); + } + } + + var processIn = function() + { + if ( ! selectedNode ) return; + + if ( selectedNode.isParent && selectedNode.open && selectedNode.children ) + { + zTree.selectNode( selectedNode.children[0] ); + return; + } + + var nextNode = selectedNode.getNextNode(); + if ( nextNode ) + { + zTree.selectNode( nextNode ); + } + else + { + // Cannot be root if there is a selected node that is not a parent + var node = selectedNode; + // Find the parent node with a valid next sibling + while( node = node.getParentNode() ) + { + var nextNode = node.getNextNode(); + if ( nextNode ) + { + zTree.selectNode( nextNode ); + break; + } + } + } + } + + var processLetter = function( keyCode ) + { + if ( ! Array.from( {length: 26}, (v, i) => i + 65 ).includes( keyCode & 95 ) ) return false; + + var nodes = zTree.transformToArray(rootNodes); + nodes = nodes.filter( node => + { + return 'accesskey' in node && node.accesskey.length && ( node.accesskey.charCodeAt(0) & 95 ) == keyCode; + } ); + + if ( ! nodes.length ) return false; + + var selectedNodes = zTree.getSelectedNodes(); + if ( ! selectedNodes.length ) return false; + + if ( selectedNodes[0] == nodes[0] ) return false; + + zTree.selectNode( nodes[0] ); + + return true; + } + + // console.log('before'); + // console.log(document.activeElement); + + switch ( e.keyCode ) + { + case 32: /* Toggle parent nodes */ + processSpace(); + return; + + case 36: /* Home - go to the root node */ + processHome(); + break; + + case 35: /* End - go to the last node */ + processEnd(); + break; + + case 33: /* PageUp */ + // Do nothing + break; + + case 34: /* PageDown */ + // Do nothing + break; + + case 37: /* Left */ + processOut(); + break; + + case 38: /* Up */ + processUp(); + break; + + case 39: /* Right */ + processIn(); + break; + + case 40: /* Down */ + processDown(); + break; + + default: + if ( ! processLetter( e.keyCode & 95 ) ) return; + break; + } + + // console.log('after'); + // console.log(document.activeElement); + focusSelectedNode(); + } ); + + $(element).trigger({ type : 'keydown', which : 36, keyCode: 36 }); + focusSelectedNode(); + } + +} )(jQuery); \ No newline at end of file diff --git a/log v3.x.txt b/log v3.x.txt index adf1fd8078b801febc278c864430d0bbafc9a80e..fddd02940be68cb54451338a83bece0be70ce0e5 100644 --- a/log v3.x.txt +++ b/log v3.x.txt @@ -14,6 +14,9 @@ +*2020.03.02* v3.5.42 + * add demo 'Keyboard Navigation' Thanks @bseddon + *2020.01.19* v3.5.42 * merge PullRequest(fixed 'HTMLElement undefined' error) Thanks @ChangJin0520 * merge PullRequest(Add TypeScript type definition) Thanks @Itroads