gordonshamway23
gordonshamway23

Reputation: 3

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

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.

Upvotes: 0

Views: 8844

Answers (3)

Danbardo
Danbardo

Reputation: 859

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 keypress 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 keypress event.

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

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

Upvotes: 0

Sachi Cortes
Sachi Cortes

Reputation: 964

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.

Upvotes: 2

mak rony
mak rony

Reputation: 21

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.

Upvotes: 0

Related Questions