【问题标题】:onKeyPress Vs. onKeyUp and onKeyDownonKeyPress 与。 onKeyUp 和 onKeyDown
【发布时间】:2015-07-21 08:38:18
【问题描述】:

这三个事件有什么区别?谷歌搜索后,我发现:

  • onKeyDown 事件在用户按键时触发。
  • onKeyUp 事件在用户释放按键时触发。
  • onKeyPress 事件在用户按下和释放键时触发 (onKeyDown 后跟 onKeyUp)。

前两个我明白,但onKeyPressonKeyUp 不一样吗?是否可以在不按下键 (onKeyDown) 的情况下释放键 (onKeyUp)?

这有点混乱,谁能帮我解决这个问题?

【问题讨论】:

  • 我发现,如果我按住 TAB 键,它会不断循环遍历所有字段,并且只会触发“onkeydown”。
  • keypress 事件表示正在输入的可用于输入的字符,例如'a'、'D'、'£'、'©'等。另一方面,keydown 和 keyup 事件表示正在键入的任何键,包括退格、制表符、向上、向下、主页、结束等。
  • "(或者是否可以在不按下 (KeyDown) 的情况下释放键 (KeyUp)?)" - 是的。例如 tab 键:keyup 事件可能不会被与 keydown 相同的元素捕获。

标签: javascript dom dom-events


【解决方案1】:

注意 KeyPress 现在是 deprecated。请改用KeyDown

KeyPressKeyUpKeyDown 分别类似于:ClickMouseUp,MouseDown

  1. Down 先发生
  2. Press 发生第二次(输入文本时)
  3. Up 最后发生(文本输入完成时)。

webkit 是个例外,其中有一个额外的事件:

keydown
keypress
textInput     
keyup

下面是一个 sn-p,您可以使用它自己查看事件何时被触发:

window.addEventListener("keyup", log);
window.addEventListener("keypress", log);
window.addEventListener("keydown", log);

function log(event){
  console.log( event.type );
}

【讨论】:

  • 那么,KeyPress 只是一个额外的事件,它是 b/w KeyDown 和 TextInput 吗?开发者一般如何使用它(KeyPress)?
  • +1 最佳答案 - *Down 首先发生,*Press 其次发生(输入文本时),*Up 最后发生(当文本输入完成时)。
  • -1 因为在 sn-p 中的一些小实验与您对“点击”事件的类比相矛盾。 'click' 事件与 'mouseup' (释放鼠标按钮时)同时触发,但 'keypress' 事件与 'keydown' (第一次按下键时)同时触发。
  • @Robusto 实际上,keypresskeydown 事件实际上被分配了相同的 .timeStamp 值,精确到 5 微秒的间隔,但这并不是我的真正意思。我的观点是click 事件在您释放 鼠标按钮之前不会触发,所以说keypressclick 的键盘版本,听起来就像keypress 一样在您 释放 键之前不会触发。事实上,情况并非如此:它在按下键时触发,就像keydown 一样。所以keypress 实际上根本不类似于click
  • @Robusto "你如何解释'keypress'总是在'keydown'之后被记录" - 简单:相同的用户操作(按下一个键)立即触发两个处理程序都被推入事件队列,但按固定顺序。 “你只是想为了争论而争论” - 嗯?您回答的核心论点是keypresskeyupkeydown 类似于clickmouseupmousedown。对我来说,对此的自然解释是keypresskeyup 在同一时刻触发(就像clickmouseup)。如果不是这样,你是什么意思
【解决方案2】:

在此处查看此答案中最初使用的存档link

从那个链接:

理论上,onKeyDownonKeyUp 事件表示按键被按下或释放,而onKeyPress 事件表示正在输入一个字符。理论的实现在所有浏览器中并不相同。

【讨论】:

  • 根据@Falk 的帖子整理一个 jsfiddle 来演示特性(使用 jquery):jsfiddle.net/zG9MF/2
  • 我看不到链接页面,但如果您打算将其用于任何类型的验证,“正在输入的字符”这一点很重要。当用户删除一个字符时,keypress 事件不会触发,因此您的验证不会触发。
  • @Tony Merryfield - 链接对我来说工作正常,我刚刚又检查了一遍。
  • @dcp - 是的,足以让我走上正确的道路。我刚刚添加了我的评论以强调事件仅在键入字符而不是任何按键时触发的观点 - 你得到了我的支持;)
  • 此外,在“长”按一个键时,KeyDown 事件会一直触发,直到该键被释放,在这种情况下 KeyUp 只会触发一次;)
【解决方案3】:

这里的大多数答案更多地侧重于理论而不是实际问题,keyupkeypress 之间存在一些很大差异,因为它与输入字段值有关,至少在 Firefox 中(在 43 中测试)。

如果用户在一个空的输入元素中输入1

  1. 输入元素的值将是keypress处理程序中的空字符串(旧值)

  2. 输入元素的值将是keyup处理程序中的1(新值)。

如果您正在做一些依赖于知道输入后的新值而不是当前值的事情,例如内联验证或自动制表符,这一点至关重要。

场景:

  1. 用户在输入元素中输入12345
  2. 用户选择文本12345
  3. 用户输入字母A

keypress 事件在输入字母A 后触发时,文本框现在只包含字母A

但是:

  1. Field.val() 是12345
  2. $Field.val().length 为5
  3. 用户选择是一个空字符串(防止您通过覆盖选择来确定删除的内容)。

看来浏览器(Firefox 43)删除了用户的选择,然后触发keypress事件,然后更新字段内容,然后 触发 keyup

【讨论】:

    【解决方案4】:

    onkeydown 在按键按下时触发(如在快捷方式中;例如,在Ctrl+A 中,Ctrl 保持“按下”状态。

    onkeyup 在释放键时触发(包括修饰键/等键)

    onkeypress 作为onkeydownonkeyup 的组合被触发,或者取决于键盘重复(当onkeyup 未被触发时)。 (这种重复行为是我没有测试过的。如果你测试过,请添加评论!)

    textInput(仅限 webkit)在输入某些文本时触发(例如,Shift+A 将输入大写的“A”,但 Ctrl+A 将选择文本而不输入任何文本输入。在这种情况下,所有其他事件被触发)

    【讨论】:

    • 刚刚确认,确实,当按键被按住时,“onkeypress”被重复调用,并且“keyboard repeat”发生。但是,“onkeydown”也是如此! (这是出乎意料的,因为它的名字)
    【解决方案5】:

    首先,它们有不同的含义:它们开火:

    • KeyDown – 当一个键被按下
    • KeyUp – 当按下的按钮释放之后 input/textarea 的值被更新(其中唯一一个)
    • KeyPress – 介于两者之间,实际上并不意味着按下并释放了一个键(见下文)。它不仅语义不一致,而且是deprecated,所以不应该使用它(另见this摘要)

    其次,有些键会触发其中一些事件,而不会触发其他事件。例如,

    • KeyPress 忽略 delete、箭头、PgUp/PgDnhome/endctrlaltshift 等,而 KeyDown 和 KeyUp 则没有(请参阅下面有关 esc 的详细信息) ;
    • 当您在 Windows 中通过 alt+tab 切换窗口时,只有 alt 的 KeyDown 会触发,因为窗口切换发生在任何其他事件之前(并且我想,至少在 Chrome 71 中,系统阻止了 tab 的 KeyDown。

    另外,您应该记住,event.keyCode(和event.which)通常对于 KeyDown 和 KeyUp 具有相同的值,但对于 KeyPress 具有不同的值。试试我创建的playground。顺便说一句,我注意到一个怪癖:在 Chrome 中,当我按 ctrl+a 并且 input/textarea 为空时,KeyPress 触发event.keyCode(和event.which)等于1! (当输入不为空时,它根本不会触发)。

    最后,还有一些语用学

    • 为了处理箭头,您可能需要使用 onKeyDown:如果用户按住 ,KeyDown 会触发多次(而 KeyUp 在释放按钮时只会触发一次)。此外,在某些情况下,您可以轻松阻止 KeyDown 的传播,但不能(或不能那么容易)阻止 KeyUp 的传播(例如,如果您想在输入时提交而不在文本字段中添加换行符)。李>
    • 令人惊讶的是,当你按住一个键时,比如在textarea 中,KeyPress 和 KeyDown 都会触发多次(Chrome 71),如果我需要多次触发的事件,我会使用 KeyDown 并使用 KeyUp 来释放单个键。
    • 当您必须对游戏的操作提供更好的响应时,KeyDown 通常更适合游戏。
    • esc 通常通过 KeyDown 处理:KeyPress 不会触发,并且 KeyUp 在不同浏览器中的 inputs 和 textareas 行为不同(主要是由于失去焦点)
    • 如果您想根据内容调整文本区域的高度,您可能不会使用 onKeyDown 而是使用 onKeyPress(PS 好的,实际上在这种情况下使用 onChange 更好) .

    我在我的项目中使用了所有 3 个,但不幸的是可能忘记了一些语用学。 (注意:还有inputchange事件)

    【讨论】:

    • 我没有想过 keyup 在字段内容中添加换行符,但这实际上很重要。
    【解决方案6】:

    Jan Wolter 的 article 是我遇到的最好的作品,如果链接失效,你可以找到存档的副本 here

    它很好地解释了所有浏览器关键事件,

    keydown 事件在按键被按下时发生,紧随其后的是 keypress 事件。然后在释放按键时产生keyup事件。

    要了解 keydownkeypress 之间的区别,区分 characterskeys 很有用。 是计算机键盘上的物理按钮。 字符是通过按下按钮键入的符号。在美式键盘上,按住 Shift 键的同时按下 4 键通常会产生“美元符号”字符。世界上的每个键盘都不一定如此。理论上,keydownkeyup 事件代表按键被按下或释放,而 keypress 事件代表一个字符被输入。在实践中,并不总是这样。

    有一段时间,一些浏览器在 keypress 之后立即触发了一个名为 textInput 的附加事件。 DOM 3 标准的早期版本打算将此作为 keypress 事件的替代品,但整个概念后来被撤销。 Webkit 在 525 和 533 版本之间支持这个,我被告知 IE 支持它,但我从未检测到,可能是因为 Webkit 要求它被称为 textInput 而 IE 称之为 textinput强>。

    还有一个名为 input 的事件,所有浏览器都支持该事件,它会在对 textarea 或输入字段进行更改后立即触发。通常按键会触发,然后键入的字符将出现在文本区域中,然后输入将触发。 input 事件实际上并没有提供任何关于键入了什么键的信息——你必须检查文本框来弄清楚发生了什么变化——所以我们并不认为它是一个键事件并且不要在这里真正记录它。虽然它最初只为文本区域和输入框定义,但我相信有一些趋势将其推广到其他类型的对象上。

    【讨论】:

    • 最佳答案,那么您如何从按键中获取美元符号?
    【解决方案7】:

    似乎 onkeypress 和 onkeydown 做的一样(只是上面已经提到的快捷键的细微差别)。

    你可以试试这个:

    <textarea type="text" onkeypress="this.value=this.value + 'onkeypress '"></textarea>
    <textarea type="text" onkeydown="this.value=this.value + 'onkeydown '" ></textarea>
    <textarea type="text" onkeyup="this.value=this.value + 'onkeyup '" ></textarea>
    

    您会看到事件 onkeypress 和 onkeydown 都是在按下键时触发的,而不是在按下键时触发的。

    不同的是,事件不是触发一次而是触发多次(只要你按住按键)。请注意这一点并相应地处理它们。

    【讨论】:

    • Ctrl、Shift、CapsLock、Backspace 和其他 不键入内容的键不会导致 keypress 事件,但它们总是会触发 keydown。跨度>
    【解决方案8】:

    更新答案:

    KeyDown

    • 按住按键时会触发多次。
    • 触发元键。

    按键

    • 按住按键时会触发多次。
    • 触发元键。

    KeyUp

    • 在您松开按键时触发一次
    • 触发元键。

    这是addEventListenerjQuery 中的行为。

    https://jsbin.com/vebaholamu/1/edit?js,console,output

    (已用正确的答案、屏幕截图和示例编辑答案)

    【讨论】:

    • 除了 keydown 也会触发多次
    • -1,因为至少在 Chrome 中至少有一个细节是错误的;正如@bluejayke 所说,当您按住某个键时,KeyDown 也会反复触发。
    • 是的,你们是对的,对不起我的错误;答案已编辑。
    • keypress 会为每个添加的字符触发,而 keydown 会不断触发(在相同的时间内放大更多次,具体取决于重复速度)
    【解决方案9】:

    onkeypress 事件适用于所有浏览器中除 ALT、CTRL、SHIFT、ESC 之外的所有键,而 onkeydown 事件适用于所有键。表示 onkeydown 事件捕获所有键。

    【讨论】:

    • keypress 也会忽略删除、箭头、home/end、PgUp/PgDn,详情请参阅我的答案(您可能也想更新答案)
    【解决方案10】:

    只是想分享一个好奇心:

    当使用 onkeydown 事件激活 JS 方法时,该事件的 charcode 与您使用 onkeypress 获得的charcode 不同!

    例如,在使用 onkeypress 时,小键盘键将返回与字母键上方的数字键相同的字符码,但在使用 onkeydown 时则不会!

    我花了好几秒钟才弄清楚为什么我的脚本在使用 onkeydown 时检查某些字符码失败了!

    演示:https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

    是的。我确实知道这些方法的定义是不同的.. 但非常令人困惑的是,在这两种方法中,事件的结果都是使用 event.keyCode 检索的.. 但它们返回的值不同.. 不是很声明式实施。

    【讨论】:

    • 数字字符的情况似乎相同(0123456789
    • 您是否注意到 keyDown 给出了键盘上的 KEY,而 keyPress 给出了我们刚刚输入(或单击)的确切字符
    【解决方案11】:

    基本上,这些事件在不同的浏览器类型和版本上的行为不同,我创建了一个小的 jsBin 测试,您可以检查控制台以了解这些事件在您的目标环境中的行为方式,希望对您有所帮助。 http://jsbin.com/zipivadu/10/edit

    【讨论】:

      【解决方案12】:

      一些可能对决定处理哪个事件有用的实际事实(运行下面的脚本并关注输入框):

      $('input').on('keyup keydown keypress',e=&gt;console.log(e.type, e.keyCode, e.which, e.key))
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <input/>

      按下:

      • 非插入/键入键(例如 ShiftCtrl)不会触发 keypress。按 Ctrl 并松开:

        keydown 17 17 控制

        keyup 17 17 控制

      • 将字符转换应用于其他字符的键盘键可能会导致 Dead重复“键”(例如 ~ ´) 在keydown。按下 ´ 并释放它以显示双 ´´:

        keydown 192 192 死亡

        keydown 192 192 ´´

        按键 180 180 ´

        按键 180 180 ´

        keyup 192 192 死亡

      此外,非键入输入(例如范围 &lt;input type="range"&gt;)仍将根据按下的键触发所有 keyup、keydown 和 keypress 事件。

      【讨论】:

        【解决方案13】:

        BLAZOR....

        如果您想检查按下了哪个键,请使用 onkeypress 或 onkeydown,但如果您想从文本字段中获取文本,然后检查最后按下的键,例如您正在扫描条形码,并且您想触发偶数按下 ENTER 键(几乎所有条码扫描仪最后都会发送 13 个“ENTER”)然后您应该使用 onkeyup 否则您将无法在文本字段中输入文本。

        例如

        这将在您通过键入代码按 Enter 后立即调用 BarCodeScan 函数,或者如果您从扫描仪扫描它,则将自动调用 BarCodeScan 函数。如果您将在此处使用“onkeypress”或“onkeydown”,则不会发生绑定,并且您将无法从文本字段中获取文本。

        【讨论】:

        • Microsoft Blazor 服务器和 WebAssembly 应用程序...(ASP .NET 核心)
        • 啊。您可能会修改您的答案以使其更清楚。在此之前,此页面上没有提及它。
        猜你喜欢
        • 2017-09-25
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        相关资源
        最近更新 更多