2
\$\begingroup\$

I am creating a VueJS component of an audio player.

I am having some difficulties in finding the ideal way to get the arrow keys and space bar to work.

I have found a solution, however I think it is not the best, nor the most effective. I've added an event listener to the DOM in the component, but the problem is that I will have multiple players along the page, so I will have multiple DOM listeners.

Is it a good solution or is there a better one?

    // component code
    ...

     document.addEventListener( 'keydown', event => {
        if ( !state.isPlaying )
            return;

        switch ( event.keyCode ) {
            case 32:
                pause();
                break;
            case 37:
                audio.currentTime -= 2;
                break;
            case 39:
                audio.currentTime += 2;
                break;
            default:
                break;
        }
    });
```
\$\endgroup\$
2
\$\begingroup\$

Determining the key pressed

The code contains this line:

switch ( event.keyCode ) {

Looking at the MDN documentation for keyCode we see:

Deprecated

This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

There is the related StackOverflow post .keyCode vs. .which from 2010 and the accepted answer has been updated with recent information about using code though browser support isn't complete so you should consider which browsers your users might use (e.g. IE?)

The VueJS documentation for Event handling even has a section about Key Codes.

The use of keyCode events is deprecated and may not be supported in new browsers.

Using keyCode attributes is also permitted:

<input v-on:keyup.13="submit">

Vue provides aliases for the most commonly used key codes when necessary for legacy browser support:

  • .enter
  • .tab
  • .delete (captures both “Delete” and “Backspace” keys)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

Those could be used in the template instead of the script section.

<player @keyup.space="pause" @keyup.right="audio.currentTime -= 2" ...>

Perhaps a method could be created to add (or subtract time) for the left and right arrow keys - e.g.:

methods: {
    addTime: function(delta) {
        audio.currentTime += delta
    }

Then that method can be used in the template:

<player @keyup.space="pause" @keyup.left="addTime(-2)" @keyup.right="addTime(2)">

Multiple handlers

If there is a need to have multiple players and a single event handler then an Event bus might be an ideal solution. There are multiple guides for creating an Event Bus (e.g. on digitalocean.com, medium.com, vuejsdevelopers.com) but I don't see one in the vueJS documentation.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for such a detailed answer. \$\endgroup\$ – martinho Sep 23 '20 at 16:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.