People press shift while on my tab, but release it on another. How to prevent Ctrl+Shift+Tab from breaking my "shift_pressed" variable?

Advertisements

I am working on a to-do list browser application (written in JavaScript, HTML and CSS, no jQuery), and I wanted to add custom behaviour for tab and shift + tab, because those should be indentation rather than navigation. Since there is no way to catch a key combination directly, I created a shift_pressed variable that detects when shift is pressed:

document.addEventListener('keyup', function (event) {
    if (event.key === 'Shift') {
        shift_pressed = false;
    }
});

document.addEventListener('keydown', function (event) {
    if (event.key === 'Shift') {
        shift_pressed = true;
    } else if (event.key === "Tab") {
        event.preventDefault();
        if (shift_pressed) {
            minus_indent();
        } else {
            plus_indent();
        }
    }
});

This works great, as long as the user stays on my tab. However, when someone uses control+shift+tab to move to the previous tab in their browser, they press shift on my tab, causing the shift_pressed variable to become true. Then, they release it on another tab, causing shift_pressed to stay true, even if they return. They then need to press and release shift again to fix it.

I decided, if the issue is control+shift+tab, let’s just catch control as well. So I did this:

document.addEventListener('keyup', function (event) {
    if (event.key === "Control") {
        ctrl = false;
    }
document.addEventListener('keydown', function (event) {
    if (event.key === 'Shift') {
        if (!ctrl) {
            shift_pressed = true;
        }
    } else if (event.key === "Control") {
        ctrl = true;
    }

This works, as long as people navigate tabs only using control+tab or control+shift+tab.
When they navigate away, control must be pressed, and when they navigate back, control must be released on my tab, so this works.

The problem is, if someone tabs away using control+shift+tab, then shift_pressed may stay false, but ctrl becomes true. And if they then navigate back not with control+tab (which would set ctrl back to false) but by clicking on the tab in their browser, ctrl stays true. This then means that shift is completely blocked from usage until they press and release control again.

>Solution :

You can make sure to reset your booleans when switching tabs, to do so you can use the following:

document.addEventListener("visibilityChange", () => {
  if (document.visibilityState === "hidden") {
    shift_pressed = false;
    ctrl = false;
  }
});

Leave a ReplyCancel reply