onKeyPress Vs. onKeyUp和onKeyDown

这三件事有什么不同?在谷歌上我发现:

  • 当用户按下一个键时触发onKeyDown事件。
  • onKeyUp事件在用户释放键时触发。
  • 当用户按&时触发onKeyPress事件;释放一个键 (onKeyDown后面跟着onKeyUp).

我理解前两个,但onKeyPress不就是onKeyUp吗?是否有可能释放一个键(onKeyUp)而不按它(onKeyDown)?

这有点混乱,有人能帮我解释一下吗?

381710 次浏览

在这里查看这个答案中最初使用的存档链接

从这个链接:

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

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

KeyPressKeyUpKeyDown分别类似于:ClickMouseUp,MouseDown

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

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

keydown
keypress
textInput
keyup

下面是一个片段,你可以自己看看什么时候事件被触发:

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


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

onkeydown在键按下时被触发(就像在快捷键中;例如,在Ctrl+A中,Ctrl被“按下”。

onkeyup在键释放时被触发(包括修饰符/etc键)

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

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

似乎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事件都是在按下键时触发的,而不是在按下键时触发的。

不同之处在于,事件不是一次触发,而是多次触发(只要您按住键)。要意识到这一点,并相应地处理它们。

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

onkeypress事件适用于所有浏览器中除ALT, CTRL, SHIFT, ESC以外的所有键,其中onkeydown事件适用于所有键。意思是onkeydown事件捕获所有的键。

首先,它们有不同的含义:它们发射:

  • KeyDown -当一个键是下推
  • KeyUp -当按下的按钮是发布,并且时,input/textarea的值会被更新(这是其中唯一的一个)
  • KeyPress -在这些和之间实际上并不意味着按下一个键,然后松开(见下文)。它不仅语义不一致,而且它是弃用,所以不应该使用它(另见 summary)

第二,一些键触发其中一些事件,而不触发其他事件。例如,

  • KeyPress忽略删除,箭头,PgUp/PgDn首页/结束ctrlalt转变等,而KeyDown和KeyUp不(参见下面关于esc的详细信息);
  • 当你在Windows中通过alt+选项卡切换窗口时,只有alt的KeyDown被触发,因为窗口切换发生在任何其他事件之前(并且选项卡的KeyDown被系统阻止,我想,至少在Chrome 71中)。

另外,你应该记住event.keyCode(和event.which)通常对KeyDown和KeyUp有相同的值,但对KeyPress有不同的值。试试我创建的操场上。顺便说一句,我注意到一个奇怪的:在Chrome浏览器中,当我按ctrl+一个input/textarea是空的,按键火灾与event.keyCode(和event.which)等于1!(当输入不为空时,它根本不会触发)。

最后,还有一些语用学:

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

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

这里的大多数答案更多地集中在理论而不是实际问题上,并且在keyupkeypress之间有一些很大的差异,因为它涉及到输入字段值,至少在Firefox中是这样(在43中测试)。

如果用户在空输入元素中输入1:

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

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

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

场景:

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

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

但是:

  1. Field.val()是12345
  2. 美元Field.val()。length是5
  3. 用户选择是一个空字符串(防止您通过覆盖选择来确定删除了什么)。

因此,似乎浏览器(Firefox 43)擦除用户的选择,然后触发keypress事件,然后更新字段内容,然后触发keyup

这个由Jan Wolter编写的文章是我遇到的最好的作品,如果链接失效,你可以找到存档副本在这里

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

keydown事件发生在按键被按下时,紧跟着按键事件。然后在释放密钥时生成按键弹起事件。

为了理解keydown键盘按键之间的区别,区分字符是有用的。关键是计算机键盘上的一个物理按钮。字符是通过按按钮输入的符号。在美国键盘上,按4键同时按住转变键通常会产生“美元符号”。的性格。这并不是世界上每个键盘都适用的情况。理论上,keydown按键弹起事件表示按键被按下或释放,而键盘按键事件表示字符被输入。在实践中,这并不总是实现的方式。

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

还有一个被称为输入的事件,所有浏览器都支持,它会在对文本区域或输入字段进行更改后触发。通常情况下,按键将触发,然后输入的字符将出现在文本区域,然后输入将触发。输入事件实际上并没有给出任何关于输入了什么键的信息——你必须检查文本框才能找出发生了什么变化——所以我们并不认为它是一个键事件,也没有在这里真正记录它。虽然它最初只是为文本区域和输入框定义的,但我相信有一些运动可以将它泛化到其他类型的对象上。

只是想分享一个好奇心:

当使用onkeydown事件来激活一个JS方法时,该事件的charcode与你使用onkeypress得到的不一样!

例如,当使用onkeypress时,numpad键将返回与字母键上方的数字键相同的字符代码,但当使用onkeydown时则不是!

我花了相当多的时间来弄清楚为什么我的脚本在使用onkeydown时检查某些字符码失败!

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

是的。我知道方法的定义是不同的。但非常令人困惑的是,在这两个方法中,事件的结果是使用event. keycode ..但是它们不会返回相同的值。不是一个非常声明性的实现。

答:更新

KeyDown

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

键盘按键

  • 当你按住键时,会触发多次。
  • 是否触发元键。

按键弹起

  • 当你释放key时,在结束时触发一次
  • 触发元键。

这是addEventListenerjQuery中的行为。

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

显示按住SSS

(答案已编辑,回复正确,截图&例子)

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

$('input').on('keyup keydown keypress',e=>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/>

压:

  • 非插入/键入键(例如转变Ctrl)将不会触发keypress。按Ctrl并释放它:

    按键17 17控制

    按键17 17控制

    李< /引用> < / >
  • 键将字符转换应用到其他字符可能导致keydown上的重复的“钥匙”(例如´)。按´并释放它,以显示双´´:

    死亡192

    按键192 192´´

    按键180°180°

    按键180°180°

    死了192

    李< /引用> < / >

此外,非键入输入(例如,远程<input type="range">)仍然会根据按下的键触发所有的keyup, keydown和keypress事件。

BLAZOR……

如果你想检查哪个键被按下,使用onkeypress或onkeydown,但如果你想从文本字段中获取文本,然后检查最后按下的键,例如,你正在扫描条形码,你想在按下ENTER键时触发一个even(几乎所有的条形码扫描器都会发送13 "ENTER"在最后),那么你应该使用onkeyup,否则你不会得到文本字段输入的文本。

例如

& lt;输入类型=“text"类=“form-control"@bind =“@barcode"@onkeyup =“BarCodeScan"占位符=“Scan"/比;

这将调用BarCodeScan函数后,你将立即按enter键入的代码,或者如果你从扫描仪扫描它,BarCodeScan函数将被自动调用。如果您将使用“onkeypress”;或“;onkeydown"在这里,绑定将不会发生,您将不会从文本字段中获得文本。

我观察到的keyup和keydown之间的区别是

如果我们为keydown事件附加一个事件处理程序,并记录输入框的值,即 (e.p target.value)则返回keydown事件

之前的值 但是如果我们为keyup事件附加一个事件处理程序,并记录输入框的值 它返回最新的值,包括被按下的键

让我们用例子来理解


// the latest keypressed is not shown in e.target.value
// when keydown event handler is executed
// since until the keyup is not triggered
// the input box will not have that character in its value
const searchCitiesEleKeyDown = document.querySelector("#searchCities");
searchCitiesEleKeyDown.addEventListener("keydown", (e) => {
console.log(e.target.value);
});




// but in case of keyup event the e.target.value prints
// the text box content with the latest character pressed
// since as soon as the keyup event triggers
// the input box will have that character pressed in its value
const searchCitiesEleKeyUp = document.querySelector("#searchCities");
searchCitiesEleKeyUp.addEventListener("keyup", (e) => {
console.log(e.target.value);
});
<input type="text" id="searchCities" />
< p > CodeSandbox链接 https://codesandbox.io/s/keydown-vs-keyup-wpj33m < / p >