2

The Internet is full of ideas on this one, but many of them are dated, and many of them are platform specific.

If I want to respond to a keyboard shortcut for save (⌘S on Mac, control-S on Linux/Windows), I know I can try something like this:

document.onkeypress=doit;
function doit(event) {
    if(event.metaKey||event.ctrlKey) {
        switch(event.key) {
            case s: doSomething();
                break;
            //  etc
        }
    }
}

The problem is the metaKey should only work on Mac, while ctrlKey should only work on Linux/Windows. Also, I can’t find a simple answer to whether I should use the keypress event or keyup or keydown.

The question is, what is the preferred way of doing this?

Manngo
  • 14,066
  • 10
  • 88
  • 110
  • Why is is a problem? Those properties are defined by the event and exist on all browsers that implement the spec, regardless of platform. Either way, `keypress` is [deprecated](https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event), so you'll want to use `keyup`/`keydown`, and really the only difference is preference. If you're implementing chords, you will probably want to react to both `keydown` and `keyup` – Tibrogargan Nov 19 '22 at 07:22
  • sorry if am wrong but maybe you can Detect device type and if device is mac assgin metaKey ig... – Dreamy Player Nov 19 '22 at 07:30
  • @Tibrogargan For example `windows-s` opens up a search while `⌘-s` means save. I should be able to let the windows key do what Windows users expect. – Manngo Nov 19 '22 at 07:45
  • @Tibrogargan Thanks for the note on `keypress` being deprecated. That simplifies the choice a little. – Manngo Nov 19 '22 at 07:46

2 Answers2

0

OK, here is a solution.

Using that, I can use something like:

document.addEventListener('keydown',doit);
function doit(event) {
    if(event.metaKey || event.ctrlKey) {
        switch(event.key) {
            case s:
                doSomething();
                event.preventDefault();     //  Don’t Save
                break;
            //  etc
        }
    }
}

This doesn’t distinguish when a Mac user presses ctrl-s, but any Mac user who does that should expect a surprise.

Manngo
  • 14,066
  • 10
  • 88
  • 110
  • The windows key isn't triggering the property because the operating system is handling it (and effectively does `event.preventDefault()`). See [KeyCode for Windows Key](https://stackoverflow.com/a/36458787/2487517) – Tibrogargan Nov 19 '22 at 21:58
0

You might find Keystrokes helpful. It has no dependencies and is very easy to use.

Using it, your code would look like this:

import { bindKeyCombo } from '@rwh/keystrokes'

bindKeyCombo('super > s', doSomething)
bindKeyCombo('ctrl > s', doSomething)
Robert Hurst
  • 8,902
  • 5
  • 42
  • 66