热门标签 | 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



推荐阅读
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Excel数据处理中的七个查询匹配函数详解
    本文介绍了Excel数据处理中的七个查询匹配函数,以vlookup函数为例进行了详细讲解。通过示例和语法解释,说明了vlookup函数的用法和参数的含义,帮助读者更好地理解和运用查询匹配函数进行数据处理。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
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社区 版权所有