TOGOUTECH

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. javascript - "Direct Response with Node.js"- 使用不同的 Node.js 进程发送 HTTP 响应(不同于主进程) - 2

      使用Node.js服务器,我想知道是否可以并建议从委托(delegate)工作进程而不是主进程发送HTTP响应。这些工作进程本身可以是Node.js服务器,或者只是通过IPC进行通信的Node.js子进程。我不认为集群核心模块https://nodejs.org/api/cluster.html可以做我想做的事,因为在那个模型中,所有的worker都在同一个端口上监听,他们代表主进程处理所有请求。我正在寻找的是一个主要的Node.js进程,它响应所有HTTP请求,可能进行身份验证和处理一些请求,但也能够将数据密集型或CPU密集型请求委托(delegate)给工作池。假设我们有一个获取大

    2. javascript - 如何使用 ng-table 进行服务器端分页? - 2

      我的代码是$scope.loadQuestions=function(){$scope.questionCount=0;$scope.questionTable=newNgTableParams({count:[]},{total:19387,getData:function($defer,params){$scope.filter.sort=params.orderBy();$scope.filter.page=params.page();return$http.get("/api/questions",{params:$scope.filter}).then(function(re

    3. javascript - 获取所有已声明模块导入的列表 (SystemJS) - 2

      我正在使用jspm和SystemJS导入ES2015模块。是否可以通过System对象或其他任何地方获取项目中所有导入模块的列表?我可以通过System._loader.moduleRecords访问我的项目特定模块,但是我通过jspm安装的模块(例如,d3、jquery)不会出现在这个列表中。System._loader.modules包含所有模块的列表,但遗憾的是还包含转译我的代码和模块加载包所需的模块列表。System._loader.moduleRecords(项目模块)System._loader.modules(项目模块、库、转译包)我只想要一个已声明导入的列表,特别是那些

    4. javascript - Chrome 扩展的 Manifest.json 中的自定义值? - 2

      是否允许将自定义值保存在Chrome扩展的manifest.json中?因为是json,所以我想在manifest.json中保存一些信息,特别是因为ChromeAPI可以用于Opera,我需要一些区分数据。如果manifest.json中有任何自定义数据,Chrome商店会提示吗? 最佳答案 不,不允许在Chrome扩展manifest.json文件中使用自定义值。您可以引用下面给出的链接。@约翰https://developer.chrome.com/extensions/manifest您只能在manifest.json中使用

    5. javascript转到带有unicode字符的url - 2

      我有一个包含这些url的数组:["path/to/url1","path/to/url2","path/url/unicóde.txt"]我正在使用angular,通过ng-repeat我创建了一个可点击的列表,该列表执行重定向到所需的url,但是,当我点击unicodeurl时,浏览器无法找到它。我尝试使用encodeURI("path/url/unicóde"),但它检索到的是:path/url/unic%C3%B3de.txt未找到。相反,当我手动访问时:path/url/unicóde.txt(这是在ftp中,因此,我逐个文件夹直到到达文件)浏览器中的url现在说:path/u

    6. javascript - 为什么我的 Ice Candidate 请求触发了 6 次而不是 1 次? - 2

      我正在使用WebRTC编写我的第一个点对点连接应用程序,我通过socket.io连接发送的用于从对等点请求icecandidate的代码触发了6次而不是一次。这真的很令人困惑,因为如果我错误地设计了一个大请求循环,我会期望无限递归,而不仅仅是6(8个onicecandidate事件)。那么谁能告诉我为什么下面的代码会产生6个递归?这里是消息处理程序,它只是发送一条由语法控制的socket.io消息:Muveoo.Messenger.input('icecandidaterequest',data);'icecandidaterequest':function(data){console

    7. javascript - 如何从 asar 存档提供静态文件 - 2

      我正在尝试构建一个带有服务器组件的Electron应用程序,使用express进行远程控制。express模块初始化为varstaticPath=path.resolve('app/assets')setupNotifications(server);app.use(cors());app.use('/api/',json());app.use('/api/',router);app.use('/assets',express.static(staticPath));console.log('servingstaticfilesfrom:'+staticPath);Elecrondoc

    8. javascript - 如何使用 Node js 和 babel 保留正确的行号 - 2

      我有以下设置并且我的错误/堆栈跟踪有问题我是否遗漏了什么?package.json看起来像:{"name":"xxxxxx","main":"server.js","private":true,"scripts":{"start":"nodemon--exec./node_modules/.bin/babel-nodeserver.js"},"dependencies":{"babel":"^6.5.2","babel-cli":"^6.6.5","babel-preset-es2015":"^6.6.0","babel-preset-react":"^6.5.0","babel-pr

    9. javascript - 已知的 JavaScript 指令 - 2

      ECMAScript规范定义了UseStrictDirective,但允许实现定义自己的指令。来自here:ImplementationsmaydefineimplementationspecificmeaningsforExpressionStatementproductionswhicharenotaUseStrictDirectiveandwhichoccurinaDirectivePrologue.什么是已知的特定于实现的指令?在Google上快速搜索一下,除了usestrict什么也没有。我能想到useasm和usestrong.还有其他的在用吗?

    10. javascript - 谷歌浏览器导航器在线始终为真 - 2

      基于mozilla开发者网络https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine它说Returnstheonlinestatusofthebrowser.Thepropertyreturnsabooleanvalue,withtruemeaningonlineandfalsemeaningoffline.Thepropertysendsupdateswheneverthebrowser'sabilitytoconnecttothenetworkchanges.Theupdateoccurswhen

    随机推荐