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



推荐阅读
  • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
  • 实践指南:使用Express、Create React App与MongoDB搭建React开发环境
    本文详细介绍了如何利用Express、Create React App和MongoDB构建一个高效的React应用开发环境,旨在为开发者提供一套完整的解决方案,包括环境搭建、数据模拟及前后端交互。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 本文详细记录了腾讯ABS云平台的一次前端开发岗位面试经历,包括面试过程中遇到的JavaScript相关问题、Vue.js等框架的深入探讨以及算法挑战等内容。 ... [详细]
  • 关于进程的复习:#管道#数据的共享Managerdictlist#进程池#cpu个数1#retmap(func,iterable)#异步自带close和join#所有 ... [详细]
  • 我自己做了一个网站图片的抓取,感觉速度有点慢抓取4000张图片可能得用15分钟左右的时间,我百度看用线程可以加快抓取,然后创建了5个线程抓取,但是5个线程是同步执行同样的操作一个图片就 ... [详细]
  • 在项目需要国际化处理时,即支持多种语言切换的功能,通常有两种方案:单个包和多个包。本文将重点讨论单个包的实现方法。 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 在移动端开发中,多点触控手势是提升用户体验的重要手段。然而,目前只有iOS浏览器原生支持手势事件,其他设备需要通过touchstart、touchmove和touchend等基础事件进行自定义实现。本文将详细介绍如何在Vue项目中实现多点触控手势。 ... [详细]
  • 在React中使用setState时遇到错误,本文将详细分析错误原因并提供解决方案。 ... [详细]
  • 本文介绍了一种在React应用中,如何在不刷新页面的情况下清除URL中的查询参数的方法,特别是在微信授权登录后,URL中会带有授权码等参数,这些参数可能会带来安全风险。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 重要知识点有:函数参数默许值、盈余参数、扩大运算符、new.target属性、块级函数、箭头函数以及尾挪用优化《深切明白ES6》笔记目次函数的默许参数在ES5中,我们给函数传参数, ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • feat: Enhances Jest Testing Capabilities with Snapshot Support ... [详细]
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社区 版权所有