单元格导航行为

SpreadJS支持GC.Spread.Sheets.Commands中定义导航操作。这些操作允许您在脚本代码中导航Spread实例,而不需要用户去做。

SpreadJS 提供的导航操作定义在 GC.Spread.Sheets.Commands 中。 moveToNextCell:移动到下一个单元格(默认操作是按下 Tab 键)。 moveToPreviousCell: 移动到前一个单元格(默认操作是同时按下 Shift 键和 Tab 键)。 selectNextControl: 选中 spread.nextControl 所指定的元素。如果没有设置,则自动检测。 selectPreviousControl:选中 spread.previousControl 所指定的元素。如果没有设置,则自动检测。 moveToNextCellThenControl: 移动到下一个单元格时,如果有活动单元格是最后一个可见的单元格,则选中下一个控件。 moveToPreviousCellThenControl: 移动到前一个单元格时,如果有活动单元格是第一个可见的单元格,则选中前一个控件。 通过 nextControl 和 previousControl 方法来设置选择控件。例如: 调用 register 方法来设置导航键和相应的操作。例如: register 方法的参数列举如下: name: 操作的名称。 execute: 操作的执行函数。 key: 按键的 Unicode 编码。 ctrl: 按下 Ctrl 键时为 true,否则为 false。 shift: 按下 Shift 键时为 true,否则为 false。 alt: 按下 Alt 键时为 true,否则为 false。 meta: 按下 Macintosh 设备上的 Command 键或者 Windows 设备上的 Windows 键时为 true,否则为false。 当 Spread 失去焦点时,调用 hideSelection 方法来隐藏选择效果。例如:
window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 }); initSpread(spread); }; function initSpread(spread) { var sheet = spread.getSheet(0); spread.suspendPaint(); sheet.setRowCount(20); sheet.setColumnCount(10); sheet.addSpan(0, 0, 1, 7); sheet.setValue(0, 0, "按下 \'Tab\' 或 \'Shift + Tab\' 键,选区将相应移动。"); for (var i = 1; i < 20; i += 3) { for (var j = 1; j < 20; j += 3) { sheet.setValue(i, j, "测试"); } } spread.resumePaint(); var commandManager = spread.commandManager(); _getElementById("preButton").addEventListener('click', _alertHandle); _getElementById("nextButton").addEventListener('click', _alertHandle); function _alertHandle() { alert(this.value); } _getElementById("tabAction").addEventListener('change', _moveHandle); _getElementById("shiftTabAction").addEventListener('change', _moveHandle); function _moveHandle() { var id = this.id, isShift = id.indexOf("shift") === 0, value = parseInt(this.value, 10), actions = GC.Spread.Sheets.Commands, action; switch (value) { case 0: action = isShift ? actions.moveToPreviousCell : actions.moveToNextCell; break; case 1: action = isShift ? actions.selectPreviousControl : actions.selectNextControl; break; case 2: action = isShift ? actions.moveToPreviousCellThenControl : actions.moveToNextCellThenControl; break; } if (action) { commandManager.register("customCommand" + new Date().valueOf(), action, GC.Spread.Commands.Key.tab, false, isShift, false, false); } } _getElementById("nextControl").addEventListener('change', _handle); _getElementById("preControl").addEventListener('change', _handle); function _handle() { var id = this.id, isPre = id.indexOf("pre") === 0, value = this.value, control = value ? document.getElementById(value) : undefined; if (isPre) { spread.previousControl(control); } else { spread.nextControl(control); } } _getElementById("hideSelection").addEventListener('click', function () { spread.options.hideSelection = this.checked; }); function customSelectLeft(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findFirstNotNullColIndex = function (sheet, fixRow, offset, stop) { while (offset > stop) { if (sheet.getValue(fixRow, offset) !== null) { break; } offset--; } return offset; } var rangeChangeSmall = selNeedAdjust.col === activeColIndex && selNeedAdjust.colCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeColIndex : 0; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.col + selNeedAdjust.colCount - 1 - 1 : selNeedAdjust.col - 1; var findResult = findFirstNotNullColIndex(sheet, activeRowIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult >= 0) { selNeedAdjust.colCount = rangeChangeSmall ? findResult - selNeedAdjust.col + 1 : selNeedAdjust.col - findResult + selNeedAdjust.colCount; selNeedAdjust.col = rangeChangeSmall ? selNeedAdjust.col : findResult; sheet.repaint(); } } function customSelectRight(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var sheetColCount = sheet.getColumnCount(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findNextNotNullColIndex = function (sheet, fixRow, offset, stop) { while (offset < stop) { if (sheet.getValue(fixRow, offset) !== null) { break; } offset++; } return offset; } var rangeChangeSmall = selNeedAdjust.col + selNeedAdjust.colCount - 1 === activeColIndex && selNeedAdjust.colCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeColIndex : sheetColCount; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.col + 1 : selNeedAdjust.col + selNeedAdjust.colCount; var findResult = findNextNotNullColIndex(sheet, activeRowIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult <= sheetColCount) { selNeedAdjust.colCount = rangeChangeSmall ? selNeedAdjust.colCount + selNeedAdjust.col - findResult : findResult - selNeedAdjust.col + 1; selNeedAdjust.col = rangeChangeSmall ? findResult : selNeedAdjust.col; sheet.repaint(); } } function customSelectUp(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findFirstNotNullRowIndex = function (sheet, fixCol, offset, stop) { while (offset > stop) { if (sheet.getValue(offset, fixCol) !== null) { break; } offset--; } return offset; } var rangeChangeSmall = selNeedAdjust.row === activeRowIndex && selNeedAdjust.rowCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeRowIndex : 0; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.row + selNeedAdjust.rowCount - 1 - 1 : selNeedAdjust.row - 1; var findResult = findFirstNotNullRowIndex(sheet, activeColIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult >= 0) { selNeedAdjust.rowCount = rangeChangeSmall ? findResult - selNeedAdjust.row + 1 : selNeedAdjust.row - findResult + selNeedAdjust.rowCount; selNeedAdjust.row = rangeChangeSmall ? selNeedAdjust.row : findResult; sheet.repaint(); } } function customSelectDown(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var sheetRowCount = sheet.getRowCount(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findNextNotNullRowIndex = function (sheet, fixCol, offset, stop) { while (offset < stop) { if (sheet.getValue(offset, fixCol) !== null) { break; } offset++; } return offset; } var rangeChangeSmall = selNeedAdjust.row + selNeedAdjust.rowCount - 1 === activeRowIndex && selNeedAdjust.rowCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeRowIndex : sheetRowCount; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.row + 1 : selNeedAdjust.row + selNeedAdjust.rowCount; var findResult = findNextNotNullRowIndex(sheet, activeColIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult <= sheetRowCount) { selNeedAdjust.rowCount = rangeChangeSmall ? selNeedAdjust.rowCount + selNeedAdjust.row - findResult : findResult - selNeedAdjust.row + 1; selNeedAdjust.row = rangeChangeSmall ? findResult : selNeedAdjust.row; sheet.repaint(); } } function getNeedAdjustSelection(selections, rowIndex, colIndex) { var sel = null; for (var i = 0; i < selections.length; i++) { if (selections[i].contains(rowIndex, colIndex)) { sel = selections[i]; } } return sel; } commandManager.register("customSelectLeft", customSelectLeft); commandManager.register("customSelectRight", customSelectRight); commandManager.register("customSelectDown", customSelectDown); commandManager.register("customSelectUp", customSelectUp); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.left, true, true, false, false); commandManager.setShortcutKey("customSelectLeft", GC.Spread.Commands.Key.left, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.right, true, true, false, false); commandManager.setShortcutKey("customSelectRight", GC.Spread.Commands.Key.right, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.down, true, true, false, false); commandManager.setShortcutKey("customSelectDown", GC.Spread.Commands.Key.down, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.up, true, true, false, false); commandManager.setShortcutKey("customSelectUp", GC.Spread.Commands.Key.up, true, true, false, false); }; function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="zh-cn" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <p>将 “Tab 用于:” 字段更改为 “下一个控件”,然后点击 Spread 实例使其获得焦点。</p> <p>按下 Tab 键,观察焦点移动到本页面的 “上一个编辑框” 文本框。</p> <p>您可以利用此功能更改 Spread 中特定导航键的作用。</p> <div class="option-row" style="margin-bottom: 10px;"> <input type="text" id="preEdit" placeholder="上一个编辑框" title="候选上一个控件" /> <input type="button" id="preButton" title="也是候选上一个控件" value="上一个按钮" /> </div> <div class="option-row"> <input type="text" id="nextEdit" placeholder="下一个编辑框" title="候选下一个控件" /> <input type="button" id="nextButton" title="也是候选下一个控件" value="下一个按钮" /> </div> <div class="option-row"> <label>Tab 用于:</label> <select id="tabAction"> <option value="0" selected="selected">下一个单元格</option> <option value="1">下一个控件</option> <option value="2">下一个单元格后再到控件</option> </select> <label class="colorLabel">这控制着用户按下 Tab 键时发生的导航操作。</label> </div> <div class="option-row"> <label>Shift + Tab 用于:</label> <select id="shiftTabAction"> <option value="0" selected="selected">上一个单元格</option> <option value="1">上一个控件</option> <option value="2">上一个单元格后再到控件</option> </select> <label class="colorLabel">这控制着用户按下 Shift+Tab 键时发生的导航操作。</label> </div> <div class="option-row"> <label>下一个控件:</label> <select id="nextControl"> <option value="" selected="selected">未设置(自动检测)</option> <option value="nextEdit">下一个编辑框</option> <option value="nextButton">下一个按钮</option> </select> <label class="colorLabel">这定义了相对于 Spread 实例的下一个控件是哪个。</label> </div> <div class="option-row"> <label>上一个控件:</label> <select id="preControl"> <option value="" selected="selected">未设置(自动检测)</option> <option value="preEdit">上一个编辑框</option> <option value="preButton">上一个按钮</option> </select> <label class="colorLabel">这定义了相对于 Spread 实例的上一个控件是哪个。</label> </div> <div class="option-row"> <input type="checkbox" id="hideSelection" /> <label for="hideSelection">隐藏选择</label> <label class="colorLabel">勾选此框将隐藏 Spread 实例中的选择内容。</label> </div> </div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } .options-toggle { display: none; } input, select { padding: 4px 6px; margin: 4px 0; width: 100%; box-sizing: border-box; } input[type=checkbox] { width: auto; } .colorLabel { width: auto; color: #606060; display: block; } .demo-options { margin-top: 5px; } p{ padding:2px 10px; background-color:#F4F8EB; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }