草庐IT

javascript - 国际键盘如何处理 JavaScript 键盘事件?

coder 2024-12-09 原文

我写了 a text editor in JavaScript that draws directly to a Canvas element (出于各种原因,但我的主要原因是我可以将该 Canvas 作为纹理贴在 WebGL 网格上)。令人高兴的是,实现我发现的任何内容可编辑解决方案都更容易。

我很早就注意到的一件事是使用 en-US QWERTY 以外的键盘布局的人提示某些键显示不正确的字母。在对 Windows 的语言设置和屏幕键盘进行了一些摆弄之后,我创建了一个基于代码页的解决方案,该解决方案将 keyCode 直接映射到不同语言环境的字符串,而不是仅仅假设“没有修饰键的 keyCode 51 是数字 3 ”。因为它不是,所以在某些键盘上它是双引号。

但仍然有一些奇怪的地方。几个例子(请注意,所有这些例子都是基于使用 Windows 屏幕键盘,所以我只是假设这与现实相关):

  • 法国AZERTY 键盘在键入字母 U 时发送 keyDown 和 keyPressed 事件,但从不发送 keyUp。我假设 U 必须与另一个键结合使用,但不知道正确的行为应该是什么阻止我编写正确的代码。编辑:我还没有完全弄清楚这意味着什么,other than--perhaps--that key is only used in one word the entire French language?
  • 德国 QWERTZ 键盘有一个 ^(它不是插入符号,它看起来更大)键,其中 `(反引号)键在美式键盘上,而反引号键则是 =(等于)键在美式键盘上。在这两种情况下,它们都发送 keyDown 和 keyUp 事件,但在我使用的任何文本编辑器中似乎都没有打印任何内容,直到第二次点击它们,然后打印两个字符。这与组合标记有关吗?我找不到任何关于它的信息。编辑:These are called dead keys ,它们会创建带重音的字母。许多键盘布局都有它们。我将为此创建一个按键排序系统,该系统还有助于为更复杂的 Emacs 风格的键盘快捷键提供支持(如果有的话)。
  • 英国 QWERTY 键盘有一个反斜杠,需要使用 ALT-GRAPH 键(美式键盘上的 Right-Alt 键)。有一个 location property of KeyboardEvent 这可用于确定按下了哪个 ALT 键,但它显然在 Safari 中不可用。这是非常低的优先级,因为 Safari 通常只占我流量的 1% 或更少。但是,是否有适用于 Safari 的属性可以用作后备?编辑:我将处理这个问题,因为我的代码页系统的其余部分适用于小写和大写键之间的差异。它只是一个新的修饰键的不同代码页。我将不得不更改检测修饰键的方式,但这是一个很小的更改,实际上很容易适应键盘快捷键系统。
  • 最后,从 Windows 的语言设置来看,世界上有很多不同的键盘布局。是否有任何地方的键码和行为列表?我宁愿不必手动测试每个键盘只是为它们生成一个新的代码页。

  • 前两个问题是最大的。如果我只知道行为应该是什么,我就可以找到解决这些问题的方法。第三个问题将适合我的代码页系统,但我必须改变我阅读修饰键的方式。最后一期,我可能会花钱请人来报道。

    我不能在 100% 的时间为所有浏览器中的所有用户解决这个问题。但是我遇到的大部分信息基本上都是“不要打扰”,这听起来更像是“我不知道”。

    编辑:选择布局不是问题。如果事情对他们不起作用,我将它作为一个选项提供给用户。我认为这是在这种情况下可以做的最好的事情,但显然我会自动检测如果可以的话。鉴于已经选择了正确的布局,我真的只关心获得正确的行为。

    我想避免任何涉及 keyPress 事件的事情,因为它并不完全可靠。如果我有关于键盘布局的可靠数据源,那将不是问题。

    最佳答案

    您无法获得键盘布局...

    没有办法(使用纯 JS 解决方案)检测用户的键盘布局。

    请注意,“en-US”或“en-GB”不会映射到这些语言的任何特定/商定的键盘布局。用户的语言与他们的键如何映射到字符无关。

    您可以根据他们的 locale / language code 做出假设,但这并不能提供任何保证 - 它只会增加您迎合适当布局的可能性。

    另请参阅以下问题:

    Translate Javascript keyCode into charCode for non-U.S. keyboard layout (i.e. azerty)

    Detect keyboard layout with javascript

    ...但你可以用它输入字符:

    但是,根据您所需的浏览器支持(使用 Canvas 应该很好),您可以尝试使用 charCode属性(property):

    http://www.w3schools.com/jsref/event_key_charcode.asp

    var unicodeCharCode = e.charCode;
    

    请注意,这不会返回实际字符​​ - 您将获得代表它的数字(不是键):

    The Unicode character code is the number of a character (e.g. the number "97" represents the letter "a").



    您可以根据需要轻松地将这些代码映射到字符,或者仅使用内置函数:
    var userInput = String.fromCharCode(unicodeCharCode);
    
  • 聪明/为自己工作,您还可以(相当简单地)编写一个库来从某些 keyCode 返回的 charCode 猜测键盘布局。不过不要:)


  • 替代方法:

    用作解决方法的一个建议是使用隐藏的(或至少是离散的)文本输入/文本框,您的应用程序将重点放在该文本框上。

    当您的应用程序检测到按键/按键等时,您可以获取用户输入的值并将其呈现在您的 Canvas 上。

    由于您已经在捕获键盘事件,因此处理组合应该很容易(如有必要)。在某些方面甚至不需要这样做,因为您只需要监视用户输入的输入长度(您的应用程序不必关心用户是否需要三键组合来输入字符,您只需捕获结果)。

    关于javascript - 国际键盘如何处理 JavaScript 键盘事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27861122/

    有关javascript - 国际键盘如何处理 JavaScript 键盘事件?的更多相关文章

    1. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

      我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

    2. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

      我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

    3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

      是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

    4. 阿里云国际版免费试用:如何注册以及注意事项 - 2

      作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

    5. ruby-on-rails - 事件记录 : Select max of limit - 2

      我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

    6. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

      我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

    7. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

      假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

    8. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    9. ruby-on-rails - 事件管理员和自定义方法 - 2

      这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

    10. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

      例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

    随机推荐