简体   繁体   English

keydown 事件中的 preventDefault() 是否会阻止以下按键事件?

[英]Does preventDefault() in keydown event prevent a following keypress event?

I have a simple html page with a webgl canvas and javascript attached.我有一个带有 webgl 画布和 javascript 的简单 html 页面。 In the script i listen to 'keydown', 'keypress' and 'keyup' events of the canvas.在脚本中,我收听画布的“keydown”、“keypress”和“keyup”事件。 Inside the eventhandlers i log to debug when the events are triggered.在事件处理程序中,当事件被触发时,我会登录以进行调试。 If i call preventDefault() on the event object in the 'keydown' handler i don't get 'keypress' events anymore and wonder if this is intended behavior?如果我在“keydown”处理程序中的事件对象上调用 preventDefault() ,我不会再收到“keypress”事件并想知道这是否是预期行为? So if i press for example a character key like 'a', the keydown and keyup events are fired, but keypress is only called if i preventDefault() is not called in the keydown event handler.因此,例如,如果我按下像“a”这样的字符键,则会触发 keydown 和 keyup 事件,但只有在 keydown 事件处理程序中未调用 preventDefault() 时才会调用 keypress。

I tested this on windows, firefox and chrome so far.到目前为止,我在 windows、firefox 和 chrome 上对此进行了测试。

index.html:索引.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Main</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="mobile-web-app-capable" content="yes" />
    <style>
        body,html { margin:0; padding:0; background-color:black; width:100%; height:100%; }
        canvas#webgl { width:100%; height:100%; }
    </style>
</head>
<body>
    <canvas id="webgl" tabindex="0"></canvas>
    <script type="text/javascript" src="test_canvaskeypress.js"></script>
</body>
</html>

test_canvaskeypress.js: test_canvaskeypress.js:


var canvas = document.getElementById("webgl"); 
canvas.addEventListener('keydown',this.onKeyDown,false);
canvas.addEventListener('keyup',this.onKeyUp,false);
canvas.addEventListener('keypress',this.onKeyPress,false);


function onKeyDown(e) {
    console.log('keyup: '+e.keyCode); 
    e.preventDefault();//prevents the keypress event, is this intended behavior?
    e.stopPropagation();

}
function onKeyUp(e) {
    console.log('keydown: '+e.keyCode); 
    e.preventDefault();
    e.stopPropagation();
}
function onKeyPress(e) {
    console.log('keypress: '+e.key); 
    e.preventDefault();
    e.stopPropagation();
}

I don't know what to expect, because the docs for preventDefault are not very informative, but i think a keypress event should appear nonetheless preventDefault is called in onKeyDown(), because the key up event also is fired.我不知道会发生什么,因为 preventDefault 的文档信息量不大,但我认为应该出现一个按键事件,但在 onKeyDown() 中调用 preventDefault,因为 key up 事件也被触发。

From the most recent W3C Working Draft ( https://www.w3.org/TR/uievents/#keydown ) we can see that one of the keydown default actions is the keypress event (among others)!从最新的 W3C 工作草案 ( https://www.w3.org/TR/uievents/#keydown ) 中,我们可以看到 keydown 默认操作之一是 keypress 事件(等等)! So, when you do a preventDefault on the keydown event, you are actually preventing the event default actions, and in this case, one of those actions is the keypress event.因此,当您对 keydown 事件执行 preventDefault 时,您实际上是在阻止事件默认操作,在这种情况下,这些操作之一是 keypress 事件。

stopPropagation stops the event from bubbling up the event chain. stopPropagation阻止事件在事件链中向上冒泡。

preventDefault prevents the default action the browser makes on that event preventDefault阻止浏览器对该事件进行的默认操作

So, If you want all the three methods to get fired remove stopPropagation() from all the three events.因此,如果您希望所有三个方法都被触发,请从所有三个事件中删除stopPropagation() Hope it will work.希望它会起作用。

I noticed a similar issue.我注意到一个类似的问题。

I was trying to prevent the Space bar from causing the page to scroll.我试图防止空格键导致页面滚动。

I added preventDefault to all key events to prevent the page scrolling.我为所有关键事件添加了preventDefault以防止页面滚动。 It worked, but it also stopped the keypressed event from firing.它起作用了,但它也阻止了keypressed事件的触发。 I needed this event elsewhere, so I had to find a work around.我在其他地方需要这个活动,所以我不得不找到一个解决办法。

It turns out that the scroll action that the Space bar performs is triggered by the keypressed event.事实证明,空格键执行的滚动动作是由keypressed事件触发的。

To solve the problem I called preventDefault only on the keypressed event.为了解决这个问题,我只在keypressed事件上调用了preventDefault I left the keyup and keydown events untouched.我没有改变keyupkeydown事件。

Just wanted to share this in case someone in my situation stumbles upon this page.只是想分享这个以防万一我这种情况的人偶然发现了这个页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM