Subscribe on changes!

Unexpected @keyup triggering on focused input field when navigated to via keyboard "click"

avatar
Nov 28th 2023

Vue version

3.3.8

Link to minimal reproduction

https://stackblitz.com/edit/github-qhj1am

Steps to reproduce

Note: Issue relates to keyboard navigation! - not mouse.

  • Open index (Home) page and tab bring focus to button labelled Goto Two.
  • Hit enter key to effectively click button. (remember, keyboard - not mouse!)
  • Browser navigates to page two
  • Notice the text highlighting that the @keyup event has been triggered on the focused input field on the destination page.

I can't think why this should be expected behaviour. Almost as if the keyup event from pressing the enter button on the index page is being seen by page two when the focus() call is made?!

Open the browser devtools to see console.log messages also show the flow of lifecycle and other events firing.

Also, to add additional context/relevant to help diagnose the error. In the script for page Two.vue there is another option (2) that can be uncommented and option (1) commented out. This only calls focus() after a delay. With this in place the issue doesn't happen.

What is expected?

My expectation is that keyboard events generated by the Home page have been cancelled by the time the router moves to the destination page.

What is actually happening?

It appears that the keyboard generated click event from pressing enter key on Home page is also generating a keyup event that lives long enough to trigger a keyup event on the new route/page.

System Info

System:
    OS: macOS 13.6.2
    CPU: (12) arm64 Apple M2 Pro
    Memory: 79.48 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.18.2 - ~/.nvm/versions/node/v18.18.2/bin/node
    npm: 9.8.1 - ~/.nvm/versions/node/v18.18.2/bin/npm
  Browsers:
    Chrome: 119.0.6045.159
    Safari: 17.1

Any additional comments?

I experienced this on Nuxt and after posting on Nuxt repo was advised to check whether it could be reproduced as a vue issue which I did.

This issue is disguised whenever the site has page transitions enabled as I assume that provides a suitable delay for the keyup events to dissipate.

Additional, self-evident but the focus() is a key aspect of this reproduction as without the input control being focused the keyup won't fire.

Thanks for your help with this!

avatar
Nov 28th 2023

This is not particularly suprising, I think. The keyup event fires when your finger has left the key. But because Vue/Nuxt renders the new view so fast, that update and the application of the focus to that input happen before you lift up your finger.

So the keyup event fires after the route has been changed and the focus has been applied to the input.

avatar
Nov 28th 2023

See here for a plain JS demo:

https://jsfiddle.net/mreqL01w/

Depending on how fast you hit/let go of enter, you can trigger this reliably with the set 100ms timeout.

if you change the timeout from 100ms to something like 300ms, your enter key stroke will typically no longer trigger the keyup.

Solution: Use an adiditional keydown event and some kind of variable you check in the keyup event handler to assure that the keyup event was in fact triggered from that input.

avatar
Nov 28th 2023

Hey @LinusBorg. Ok, appreciate knowing it's expected behaviour and I can work around it on that basis. Thanks for the quick response!