13
votes

My app changes its state when a person holds modifier keys (Shift, Alt, Ctrl). I track modifier keys using keydown/keyup events:

var altPressed;
window.onkeydown = window.onkeyup = function(e) {
    altPressed = e.altKey;
}

Keyboard events don’t trigger outside of the browser tab. Now, imagine the following scenario:

  1. Hold Shift key
  2. Click on a link to my app, it will open in a new window
  3. Release Shift key

keyup event won’t fire on my page when it isn’t focused so my app will show when I focus on my app’s tab again it will show the Shift key still being pressed.

Would be nice if page visibility events had modifier key properties. Alas, they don’t.

document.addEventListener('webkitvisibilitychange', function(e) {
    if (document.webkitHidden) return;

    e.altKey // undefined :(

}, false);
2
So, you want to know what keys were pressed down before the page was loaded? If so, it might be a rough road...rvighne
can you give a reason why you want to do that? the page could be loaded in background so it could not always get the key eventcharlee
What problem are you actually trying to solve? So far, it looks like you're just describing a behavior you've observed and I'm not seeing a particular problem description that you need help with solving.jfriend00
@jfriend00: Check out the original revision; for some reason the OP edited out the actual question.rvighne
I think the point is for alt/shift/etc to not still be pressed after returning to the app, in better terms, to detect it has been released when returning to the app.JDuarteDJ

2 Answers

4
votes

The best I came up so far:

document.body.onkeydown = function(e) {
  if (e.which === 18) {
    alt_state.textContent = 'pressed';
  }
};

document.body.onkeyup = function(e) {
  if (e.which === 18) {
    alt_state.textContent = 'released';
  }
};

function detectAlt() {
  if (document.webkitHidden) return;
  window.addEventListener('mousemove', function onMove(e) {
    alt_state.textContent = e.altKey ? 'pressed' : 'released';
    window.removeEventListener('mousemove', onMove, false);
  }, false);
}

document.addEventListener('webkitvisibilitychange', detectAlt, false);
window.addEventListener('load', detectAlt, false);

Press alt key and click on the link: jsbin.

It relies on mousemove event which, unlike load and visibilitychange events, has altKey property. As a downside, it won’t detect altKey until a person moves the mouse.

1
votes

I could think of 2 options:

  1. Use a timed "alt status" --> after 2 seconds declare alt unpressed.

    document.body.onkeydown = function(e) { if (e.which === 18) { alt_state.textContent = 'pressed'; setTimeout(function(){ alt_state.textContent= ""; },2000); } };

  2. When visibility is lost simply reset all alt flags.

    document.addEventListener('webkitvisibilitychange', function(e) {
        if (document.webkitHidden){
            altPressed = "";
            return;
        }
    }, false);
    

try this: http://jsbin.com/jihuyibu/1/edit It's my best guess, even so it never comes out perfectly.