React和几行代码可以挽救!
我想像一个场景。 您在一家名为Adob的大公司工作……您在一家名为Abode的初创公司工作,开发了一个名为PhotoStore的照片编辑应用程序。 听起来像是图像存储服务,但事实并非如此! 实际上,这是流行的桌面应用程序的基于Web的替代方法。
有一天,您的产品经理宣布,由于您的竞争对手拥有键盘快捷键,因此您也需要它们来使现有用户更容易切换。 毕竟,这不应延迟我们的发布。 您将只添加document.addEventListener('keydown',callback); 就完成了,对吗?
好吧,不是那么快。 为什么我们需要快捷方式? 在我们的情况下,我们希望能够激活工具栏中的各种工具(例如“画笔”或“选择”)。 但是即使在简单的用例中,我们也可以合理预期需要处理以下内容。
- 激活所选工具(状态管理)
- 突出显示所选工具(CSS样式)
- 仅在编辑器中执行上述所有操作(快捷方式在营销页面,指南等中不起作用)
在我们编写代码之前,最好考虑一下将来功能如何发展。 通过以支持此理论功能的方式设计解决方案,即使我们决定此时不实施,也可以避免很多麻烦。
为什么还要打扰?
您认为: “这不适用于我,我不在开发照片编辑应用程序。”
尽管这可能是正确的,但每个应用程序的用户都会养成习惯并采用某些工作流程。 这包括您的应用程序。 提供最常用功能的键盘快捷键可使您的用户更快,更高效,从而更快乐。
有时,您的用户无法或不想使用其鼠标,这使得快捷方式几乎成为产品的必要部分。 在这些情况下,我什至将它们视为整体可访问性策略的一部分。 您确实在乎,对吗? 我也那么认为。 因此,让我们开始吧。
先决条件。
我们需要什么来提供这种愉快的体验? 对于本文,我将“仅” React与JSX结合使用 ,从而使我能够编写紧凑的代码。 我只用引号引起来,因为如果您以前从未使用过React,设置React可能会令人生畏。
但是,如果您要向应用程序添加快捷方式,则很有可能已经使用了一些SPA框架。 我们需要的是onCreate()和onDestroy()生命周期方法,因此,如果您的框架提供了等效的方法,那么本指南将很容易遵循。 在React中,这些方法称为componentDidMount()和componentWillUnmount() 。
如果您使用普通的Javascript,请不要惊慌,仍然可以继续。 我们将专注于概念,而不是特定的实现。 但是您应该能够阅读ES6 ,因为我不关心冗长的代码寿命。
项目设置。
我设法获得了Abode PhotoStore应用程序并将其发布到CodePen,因此您可以快速上手并继续学习。 (希望,Abode不会因为泄漏他们的产品而起诉我们。)
如您所见,我获得了他们系统的早期版本。 他们还没有聘请设计人员,只有2种工具可供选择-画笔和选择。 我们还可以在页面之间切换。 这很方便,因为我们将要确保快捷方式仅在编辑器中有效。 因此,对于我们的需求,这就足够了。
概念。
此功能将如何工作? 我们将需要创建以下内容。
- 可用的快捷方式。 这将是我们可以调用的快捷方式列表。 它们将映射到包含所有应用程序快捷方式的对象。
- 听众。 我们希望确保快捷方式仅在编辑器中有效。 我们的框架的生命周期方法将在这里派上用场。
- 处理程序。 处理键盘事件和实际快捷键执行的功能。
实施。
让我们从定义应用程序快捷方式开始。 这将是可在应用程序中执行的所有快捷方式的对象。 目前,我们只能从工具栏中选择工具。 每个快捷方式处理程序都是一个将KeyboardEvent对象作为单个参数接受的函数。 在执行其主体之前,它将检查事件是否与触发模式匹配。
if (event.key !== ‘b’) return false;
if (event.key !== ‘m’) return false;
为了满足只能在某些页面上执行某些快捷方式的要求,我们将提供一个当前注册的快捷方式列表。
let registeredShortcuts = [];
当用户按下某个键时,我们将遍历此列表,并查看键事件是否执行了任何快捷方式,此时我们将停止迭代。 如果改为遍历快捷键,则将快捷方式执行限制在特定页面上将更加困难。
const handleKeyDown = event => {
const shortcut = registeredShortcuts[i];
if (shortcuts[shortcut](event)) {
要开始监听按键,我们注册了一个全局监听器。
document.addEventListener(‘keydown’, handleKeyDown);
现在,您可以在registeredShortcuts数组中添加“ toolBrush”和“ toolSelect” ,以查看确实确实调用了我们的快捷方式。
现在,我们已经验证了快捷方式的工作原理,可以清除数组并编写一个适当的组件,该组件将为我们处理快捷方式注册。 我们将把工具栏按钮包装在该组件中。
这具有一系列优点。 首先,当我们稍后查看代码时,很明显此快捷方式会影响应用程序的哪些部分。 通过键入在我们的项目中搜索特定的快捷方式也很容易。
通过将每个快捷方式嵌入视图的render方法中,可以将其生命周期长度绑定到父组件。 使用组件生命周期方法注册和注销快捷方式使状态管理变得轻而易举。 创建组件后,我们将注册快捷方式。 相反,我们在销毁时注销相同的快捷方式。
我和其他任何人一样都喜欢纯Javascript,但这将是一场噩梦。 这是我们的组件。
class Shortcut extends React.Component {
if (!registeredShortcuts.includes(this.props.name)) {
registeredShortcuts = [
registeredShortcuts = [
…registeredShortcuts.filter(x => x !== this.props.name),
return this.props.children || null;
现在,我们需要将工具栏更改为仅显示在编辑器视图中。 我们还向其中添加样式并删除控制台信息。 就是这样!
附录。
就像魅力一样,对不对? 我们已成功向我们的应用添加了对键盘快捷键的支持。 我们现在准备好与我们的克星竞争吗? 完全。 营销团队可以开始推广这项崭新的功能。
但是作为工程团队,我们的工作尚未结束。 也就是说,除非您打算明天辞职,并让您的继任者在这段美好的日子(如果代码中断)处理该代码。 为了简化起见,我在本文中使用了一些快捷方式(双关语是预期的)。 继续阅读以进行进一步讨论。
- 捆绑优化
- 跨浏览器支持
- 开发工具
- 边缘案例
- 模式匹配
- 快捷方式选择
- 国家管理
- 支持多种快捷方式
- 测试中
捆绑优化。
有两件事要考虑。 代替使用具有相同值的多个字符串文字,我们可以将它们替换为一个变量。 然后,可以在构建过程中最小化此变量,以减少最终程序包的部分内容。
第二点是弄清楚我们是否完全需要提供此功能? 毕竟,由于某种原因,这些被称为键盘快捷键。 您可能不希望在没有键盘的情况下将此代码提供给您的移动用户。 但是,截至2018年3月,尚没有可靠的API可检测键盘的存在。
跨浏览器支持。
本指南使用了一组现代的Javascript功能。 如果支持较旧的浏览器,则需要确保转换代码并使用较旧的浏览器API进行事件检测。
开发工具。
对于内部调试工具,如果出现问题,您可能希望查看当前已注册了哪些快捷方式。 这很简单,您只需转储registeredShortcuts的内容即可。
边缘案例。
假设有一天,我们在应用程序中添加了一个输入字段,允许用户搜索图层。 现在,如果他们要搜索“背景”层,则可以开始输入b ,但是哦,笔刷工具被选中。 那不是可能发生的最坏的情况,我们可以切换一些窗口或对话框,但这说明了问题。
对于此类错误,您将需要检查event.target,以确保它不是可写的DOM节点。
模式匹配。
是的,我们的快捷方式有效。 但是尝试按Ctrl /⌘+ B键-仍然可以选择画笔工具! 这显然不是我们想要的。 因此, 除了简单检查event.key之外 ,我们还需要添加一个精确的模式匹配功能。
快捷方式选择。
Sasha Maximova写了一篇很好的文章 ,为您的应用程序选择了快捷方式,因此我不会反驳她的观点。 就个人而言,我更喜欢将一键快捷键和Shift用于两键组合,因为它可以大大减少与任何浏览器/ OS命令发生冲突的可能性。 诸如粗体之类的格式设置函数例外,在该函数中,除了Ctrl /⌘+ B之外,无需使用其他任何功能,因为您的用户将习惯于此。
国家管理。
我限制将Redux之类的整个状态管理库放入我们的教程中,以使其简短而简单,但是您可能希望迭代管理应用程序中的状态。 我们无意间创建了一些全局变量,这些变量很容易被Redux之类的工具包含。
支持多个快捷方式。
现在,我们的函数仅接受一个字符串参数,但是在某些情况下,您可能想一次注册多个快捷方式。 例如,如果您希望在视图顶部声明所有快捷方式。
测试。
未经测试请勿发布代码。 在现有功能之上进行测试,以及发现潜在的错误,将变得更加容易。 如果您使用SPA框架(我知道您知道),那么您还需要记录您的组件,以便轻松查看它们支持哪些参数。
结论。
在应用程序中添加键盘快捷键是一项捷径,可以改善用户体验,而不会花费您的一臂之力。 仔细选择最常用的功能,并通过使他们加快工作流程来使用户满意。
感谢您的阅读。
感谢Scrimba的朋友阅读本文的草稿。 访问他们,以最简单的方式学习代码。 您可以在我的网站上从我那里了解更多信息 。
From: https://hackernoon.com/add-keyboard-shortcuts-to-your-web-app-ba358016ff05