0

I have a simple html page with a webgl canvas and javascript attached. In the script i listen to 'keydown', 'keypress' and 'keyup' events of the canvas. 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? 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.

I tested this on windows, firefox and chrome so far.

index.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:


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.

gman
  • 100,619
  • 31
  • 269
  • 393

3 Answers3

1

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)! 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.

Sachi Cortes
  • 884
  • 1
  • 11
  • 12
0

stopPropagation stops the event from bubbling up the event chain.

preventDefault prevents the default action the browser makes on that event

So, If you want all the three methods to get fired remove stopPropagation() from all the three events. Hope it will work.

mak rony
  • 21
  • 3
  • Tested it real quick and it does not work, PreventDefault still prevents the keypress event. And by the way, i dont want my events to bubble up the dom tree. And i think propagating event upwards is not needed here, because all my eventhandlers are bound to canvas and no parent elements. – gordonshamway23 Aug 07 '19 at 19:11
0

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. It worked, but it also stopped the keypressed event from firing. 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.

To solve the problem I called preventDefault only on the keypressed event. I left the keyup and keydown events untouched.

Just wanted to share this in case someone in my situation stumbles upon this page.

JoSSte
  • 2,953
  • 6
  • 34
  • 54
Danbardo
  • 761
  • 7
  • 12