Blockly 会维护一个键盘快捷键注册表,用于将按键(或按键组合,如 ctrl-C
)映射到操作。注册表已预先填充了许多快捷方式,例如用于复制的 ctrl-C
和 meta-C
。您可以向注册表中添加快捷方式,也可以从中删除快捷方式。
键盘快捷键的运作方式
快捷方式注册表包含用于对键盘快捷键建模的对象。当用户按下某个键(或组合键)时,Blockly 会执行以下操作:
检查注册表,看看是否有任何快捷方式适用于该键。如果多个快捷方式使用该键,系统会按注册顺序的反向顺序尝试这些快捷方式。也就是说,系统会先尝试最近注册的快捷方式。
调用快捷指令的
preconditionFn
函数,该函数用于确定快捷指令是否适用于当前情况。例如,复制快捷键适用于块,但不适用于工作区。如果该快捷方式不适用,Blockly 会尝试列表中的下一个快捷方式(如果有)。调用快捷方式的
callback
函数,该函数会执行快捷方式的操作。例如,复制快捷键可复制当前聚焦的对象(例如代码块)。如果此函数返回true
,处理会停止。如果返回false
,Blockly 会尝试列表中的下一个快捷方式(如果有)。
范围
Scope
对象用于标识当前获得焦点的 Blockly 组件。范围对象会传递给 preconditionFn
和 callback
,这两个函数会使用范围对象来决定快捷方式是否适用于特定组件,如果适用,则决定如何应用该快捷方式。
如需使用 Scope
对象,请使用其 focusedNode
属性。这是一个实现 IFocusableNode
的对象。用户可以聚焦的所有 Blockly 组件(包括工作区、代码块、字段、注释和您自己的自定义组件)都会实现此接口;如需了解详情,请参阅聚焦系统。
例如,preconditionFn
可能会使用 focusedNode
来确保快捷方式仅适用于块。
preconditionFn(workspace, scope) {
return (scope.focusedNode instanceof Blockly.BlockSvg);
}
KeyboardShortcut 接口
快捷方式注册表中的对象实现了 KeyboardShortcut
接口。此对象包含以下属性。
名称(必填)
快捷方式的唯一名称。此属性不会向用户显示,无需采用人类可读懂的格式。不应翻译。
const logFieldsShortcut = {
name: 'logFields',
// ...
};
preconditionFn(可选)
Blockly 会调用此函数来确定快捷方式是否适用于当前情况。如果返回 true
,Blockly 会调用 callback
。如果返回 false
,Blockly 会忽略此快捷方式。例如:
const logFieldsShortcut = {
// ...
preconditionFn(workspace, scope) {
// This shortcut only applies to blocks.
return (scope.focusedNode instanceof Blockly.BlockSvg);
},
// ...
};
如果快捷方式始终适用(不常见),则可以省略此函数。
快捷方式不应省略此函数,然后在 callback
中有条件地执行操作。这样做可防止 Blockly 执行构建显示适用快捷方式的上下文帮助菜单等操作。
回调(可选)
此函数会执行与快捷方式关联的操作。仅当 preconditionFn
返回 true
或不存在时,才会调用此方法。其参数为:
workspace
:当前的WorkspaceSvg
。e
:启动快捷方式的Event
。shortcut
:KeyboardShortcut
本身。scope
:快捷方式适用的Scope
。
如果成功,则返回 true
;如果失败,则返回 false
。
例如:
const logFieldsShortcut = {
// ...
callback(workspace, event, shortcut, scope) {
// preconditionFn required focusedNode to be a BlockSvg.
for (input of scope.focusedNode.inputList) {
// Log the values of all named fields. (Label fields usually don't have names.)
for (field of input.fieldRow) {
if (field.name) {
console.log(field.name + ': ' + field.getText());
}
}
}
return true;
},
// ...
};
虽然 callback
是可选的,但通常没有理由不实现它。
keyCodes(可选)
用于激活此快捷方式的键(或键组合)数组。如需识别按键,请使用 Blockly.utils.KeyCodes
中的键码。例如:
const logFieldsShortcut = {
// ...
keyCodes: [Blockly.utils.KeyCodes.L],
// ...
};
如果您想将其他按键映射到现有快捷键(例如,您想向默认快捷键添加按键),可以调用 Blockly.ShortcutRegistry.registry.addKeyMapping
。这种情况并不常见。
组合键
如果键盘快捷键是通过组合键(例如同时按住 Control
和 C
)激活的,请通过调用 Blockly.ShortcutRegistry.registry.createSerializedKey
创建序列化的键码:
const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C, // Keycode of main key
[Blockly.utils.KeyCodes.CTRL], // Array of modifier keys
);
const copyShortcut = {
// ...
keyCodes: [ctrlC], // Use the serialized keycode
// ...
};
Control 和 Meta
在 Windows 上,许多快捷键都是通过 Control
键激活的。在 Mac 上,这些键盘快捷键使用的是 Command
键,该键被识别为 META
键码。为了同时支持这两个操作系统,请同时注册 CTRL
按键代码和 META
按键代码。
const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C,
[Blockly.utils.KeyCodes.CTRL],
);
const metaC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C,
[Blockly.utils.KeyCodes.META],
);
const copyShortcut = {
// ...
keyCodes: [ctrlC, metaC],
// ...
};
植入注意事项
Blockly 的键盘事件处理脚本使用 KeyboardEvent
的 keycode
属性,即使该属性已被弃用。
allowCollision(可选)
默认情况下,您只能为给定的按键或按键组合注册一个快捷键。将此属性设置为 true
可让您注册按键(或按键组合),即使已注册了具有相同按键(或按键组合)的快捷键也是如此。
请注意,此属性仅在尝试注册此快捷方式时适用。
它不会阻止其他快捷方式使用相同的键(或组合键)。能否注册取决于其 allowCollision
属性的值。
无论为给定的按键或按键组合注册了多少个快捷方式,最多只会成功执行一个。系统会按注册的相反顺序(从最后注册的快捷方式到最先注册的快捷方式)尝试快捷方式。其中一个快捷方式从其回调返回 true
后,系统不会再尝试其他快捷方式。
元数据(可选)
这是一个包含其他信息的任意对象。它通过 shortcut
参数提供给 callback
。
添加、删除和修改快捷方式
如需添加新的键盘快捷键,请调用 Blockly.ShortcutRegistry.registry.register
:
Blockly.ShortcutRegistry.registry.register(logFieldsShortcut);
此函数具有第二个形参 (allowOverrides
),可用于替换与您的快捷方式同名的现有快捷方式。请注意,这与 KeyboardShortcut.allowCollision
不同,后者可让您添加名称不同的快捷方式,但使用与现有快捷方式相同的键或键组合。
如需删除键盘快捷键,请调用 Blockly.ShortcutRegistry.registry.unregister
并传递快捷键的名称:
Blockly.ShortcutRegistry.registry.unregister('logFields');
您无法就地修改键盘快捷键。而是需要删除现有快捷方式,然后添加新的快捷方式。例如:
// Get the existing shortcut. getRegistry returns an object keyed by shortcut name.
const allShortcuts = Blockly.ShortcutRegistry.registry.getRegistry();
const modLogFieldsShortcut = allShortcuts[logFieldsShortcut.name];
// Apply the shortcut only to math blocks,
modLogFieldsShortcut.preconditionFn = function (workspace, scope) {
return (scope.focusedNode instanceof Blockly.BlockSvg &&
scope.focusedNode.type.startsWith('math_'));
}
// Delete the existing shortcut and add the modified shortcut.
Blockly.ShortcutRegistry.registry.unregister(logFieldsShortcut.name);
Blockly.ShortcutRegistry.registry.register(modLogFieldsShortcut);
默认快捷键
快捷方式注册表中预先填充了许多快捷方式。您可以在 https://github.com/google/blockly/blob/master/core/shortcut_items.ts 中找到这些内容。
快捷方式在 registerXxxx
函数中定义。
键盘导航快捷键
键盘导航插件包含一些快捷键,可让用户通过键盘(例如使用箭头键)在 Blockly 中导航。对于无法使用鼠标的用户(例如行动不便或视障用户),键盘导航至关重要。对于可能希望使用键盘快捷键来提高效率的高级用户,此功能也很有用。