热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

将键盘快捷方式添加到您的Web应用程序。

React和几行代码可以挽救!我想像一个场景。您在一家名为Adob的大公司工作……您在一家名为Abode的初创公司工作,开发了一个名为PhotoStor

React和几行代码可以挽救!

我想像一个场景。 您在一家名为Adob的大公司工作……您在一家名为Abode的初创公司工作,开发了一个名为PhotoStore的照片编辑应用程序。 听起来像是图像存储服务,但事实并非如此! 实际上,这是流行的桌面应用程序的基于Web的替代方法。

有一天,您的产品经理宣布,由于您的竞争对手拥有键盘快捷键,因此您也需要它们来使现有用户更容易切换。 毕竟,这不应延迟我们的发布。 您将只添加document.addEventListener('keydown',callback); 就完成了,对吗?

好吧,不是那么快。 为什么我们需要快捷方式? 在我们的情况下,我们希望能够激活工具栏中的各种工具(例如“画笔”或“选择”)。 但是即使在简单的用例中,我们也可以合理预期需要处理以下内容。

  • 激活所选工具(状态管理)
  • 突出显示所选工具(CSS样式)
  • 仅在编辑器中执行上述所有操作(快捷方式在营销页面,指南等中不起作用)

在我们编写代码之前,最好考虑一下将来功能如何发展。 通过以支持此理论功能的方式设计解决方案,即使我们决定此时不实施,也可以避免很多麻烦。

为什么还要打扰?

您认为: “这不适用于我,我不在开发照片编辑应用程序。”

尽管这可能是正确的,但每个应用程序的用户都会养成习惯并采用某些工作流程。 这包括您的应用程序。 提供最常用功能的键盘快捷键可使您的用户更快,更高效,从而更快乐。

有时,您的用户无法或不想使用其鼠标,这使得快捷方式几乎成为产品的必要部分。 在这些情况下,我什至将它们视为整体可访问性策略的一部分。 您确实在乎,对吗? 我也那么认为。 因此,让我们开始吧。

认识您的新朋友,B和M。

先决条件。

我们需要什么来提供这种愉快的体验? 对于本文,我将“仅” React与JSX结合使用 ,从而使我能够编写紧凑的代码。 我用引号引起来,因为如果您以前从未使用过React,设置React可能会令人生畏。

但是,如果您要向应用程序添加快捷方式,则很有可能已经使用了一些SPA框架。 我们需要的是onCreate()onDestroy()生命周期方法,因此,如果您的框架提供了等效的方法,那么本指南将很容易遵循。 在React中,这些方法称为componentDidMount()componentWillUnmount()

如果您使用普通的Javascript,请不要惊慌,仍然可以继续。 我们将专注于概念,而不是特定的实现。 但是您应该能够阅读ES6 ,因为我不关心冗长的代码寿命。

项目设置。

我设法获得了Abode PhotoStore应用程序并将其发布到CodePen,因此您可以快速上手并继续学习。 (希望,Abode不会因为泄漏他们的产品而起诉我们。)

如您所见,我获得了他们系统的早期版本。 他们还没有聘请设计人员,只有2种工具可供选择-画笔和选择。 我们还可以在页面之间切换。 这很方便,因为我们将要确保快捷方式仅在编辑器中有效。 因此,对于我们的需求,这就足够了。

概念。

此功能将如何工作? 我们将需要创建以下内容。

  1. 可用的快捷方式。 这将是我们可以调用的快捷方式列表。 它们将映射到包含所有应用程序快捷方式的对象。
  2. 听众。 我们希望确保快捷方式仅在编辑器中有效。 我们的框架的生命周期方法将在这里派上用场。
  3. 处理程序。 处理键盘事件和实际快捷键执行的功能。

实施。

让我们从定义应用程序快捷方式开始。 这将是可在应用程序中执行的所有快捷方式的对象。 目前,我们只能从工具栏中选择工具。 每个快捷方式处理程序都是一个将KeyboardEvent对象作为单个参数接受的函数。 在执行其主体之前,它将检查事件是否与触发模式匹配。

const shortcuts = {

toolBrush(event) {

if (event.key !== ‘b’) return false;

useTool(‘brush’);

return true;

},

toolSelect(event) {

if (event.key !== ‘m’) return false;

useTool(‘select’);

return true;

},

};

为了满足只能在某些页面上执行某些快捷方式的要求,我们将提供一个当前注册的快捷方式列表。

let registeredShortcuts = [];

当用户按下某个键时,我们将遍历此列表,并查看键事件是否执行了任何快捷方式,此时我们将停止迭代。 如果改为遍历快捷键,则将快捷方式执行限制在特定页面上将更加困难。

const handleKeyDown = event => {

for (let i = 0; i

const shortcut = registeredShortcuts[i];

if (shortcuts[shortcut](event)) {

event.preventDefault();

break;

}

}

};

要开始监听按键,我们注册了一个全局监听器。

document.addEventListener(‘keydown’, handleKeyDown);

现在,您可以在registeredShortcuts数组中添加“ toolBrush”“ toolSelect” ,以查看确实确实调用了我们的快捷方式。

现在,我们已经验证了快捷方式的工作原理,可以清除数组并编写一个适当的组件,该组件将为我们处理快捷方式注册。 我们将把工具栏按钮包装在该组件中。

label=”Brush”

onClick={useTool}

to=”brush” />

label=”Select”

onClick={useTool}

to=”select” />

这具有一系列优点。 首先,当我们稍后查看代码时,很明显此快捷方式会影响应用程序的哪些部分。 通过键入在我们的项目中搜索特定的快捷方式也很容易。

通过将每个快捷方式嵌入视图的render方法中,可以将其生命周期长度绑定到父组件。 使用组件生命周期方法注册和注销快捷方式使状态管理变得轻而易举。 创建组件后,我们将注册快捷方式。 相反,我们在销毁时注销相同的快捷方式。

我和其他任何人一样都喜欢纯Javascript,但这将是一场噩梦。 这是我们的组件。

class Shortcut extends React.Component {

componentDidMount() {

if (!registeredShortcuts.includes(this.props.name)) {

registeredShortcuts = [

…registeredShortcuts,

this.props.name,

];

}

}

componentWillUnmount() {

registeredShortcuts = [

…registeredShortcuts.filter(x => x !== this.props.name),

];

}

render() {

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



推荐阅读
  • 详解react组件通讯方式(多种)
    这篇文章主要介绍了详解react组件通讯方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • python3 nmap函数简介及使用方法
    本文介绍了python3 nmap函数的简介及使用方法,python-nmap是一个使用nmap进行端口扫描的python库,它可以生成nmap扫描报告,并帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。文章详细介绍了python-nmap的几个py文件的功能和用途,包括__init__.py、nmap.py和test.py。__init__.py主要导入基本信息,nmap.py用于调用nmap的功能进行扫描,test.py用于测试是否可以利用nmap的扫描功能。 ... [详细]
  • wpf+mvvm代码组织结构及实现方式
    本文介绍了wpf+mvvm代码组织结构的由来和实现方式。作者回顾了自己大学时期接触wpf开发和mvvm模式的经历,认为mvvm模式使得开发更加专注于业务且高效。与此同时,作者指出mvvm模式相较于mvc模式的优势。文章还提到了当没有mvvm时处理数据和UI交互的例子,以及前后端分离和组件化的概念。作者希望能够只关注原始数据结构,将数据交给UI自行改变,从而解放劳动力,避免加班。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • 工作经验谈之-让百度地图API调用数据库内容 及详解
    这段时间,所在项目中要用到的一个模块,就是让数据库中的内容在百度地图上展现出来,如经纬度。主要实现以下几点功能:1.读取数据库中的经纬度值在百度上标注出来。2.点击标注弹出对应信息。3 ... [详细]
  • 本文介绍了三种方法来关闭win7电脑开机硬盘自检,分别是使用命令提示符、注册表编辑器和bios设置界面。通过取消硬盘自检可以加快电脑启动速度。详细步骤和操作说明在正文中有详细介绍。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 如何更改电脑系统的自动校时服务器地址?
    本文介绍了如何通过注册表编辑器更改电脑系统的自动校时服务器地址。通过修改注册表中的数值数据或新建字符串数值的方式,可以将默认的时钟同步服务器地址更改为自己所需要的域名或IP地址。详细步骤包括双击时间区域,点击internet时间,勾选自动校正域名设置定时等操作。 ... [详细]
  • 广度优先遍历(BFS)算法的概述、代码实现和应用
    本文介绍了广度优先遍历(BFS)算法的概述、邻接矩阵和邻接表的代码实现,并讨论了BFS在求解最短路径或最短步数问题上的应用。以LeetCode中的934.最短的桥为例,详细阐述了BFS的具体思路和代码实现。最后,推荐了一些相关的BFS算法题目供大家练习。 ... [详细]
  • 一、修改注册表去掉桌面图标小箭头1按下win+R组合快捷键,打开windows10系统的“运行”窗口,输入“regedit”,打开注册表编辑器,找到HKEY_CLASSES_ROOT\lnkfi ... [详细]
author-avatar
闫小芽_209
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有