4

In a SPA,, specifically Vuejs, I need to reset the tab index of the page when I access a new route

I tried this:

watch: {
    $route (to, from) {
        document.getElementById('content').focus()
        // or
        // document.body.focus()
        // or
        // window.focus()
    }
}

I tried placing the same code to:

beforeRouteEnter (to, from, next) {
    next(vm => vm.resetFocus())
},
methods: {
    resetFocus() {
        document.getElementById('content').focus()
        // or
        // document.body.focus()
        // or
        // window.focus()
    }
}

I AM ABLE to set focus on a ref="focus" in my main template but this gets the element displayed and it is not an ideal scenario. I need window or body to be focused as it is when the page loads.

Component template:

<template>
    <div id="app">
    <a class="sr-only sr-only-focusable skip-link" ref="focus" href="#content">Go to main content</a>
    <navigation><navigation/>
    <main id="content">
        <router-view></router-view>
    </main> 
    </div>
</template>

In my component code:

    methods: {
        setFocus(){
            this.$refs.focus.focus()
        }
    },
    watch:{
        $route (to, from){
            this.setFocus()
        }
    },

Neither attempts give me any results..

GRowing
  • 4,629
  • 13
  • 52
  • 75

1 Answers1

1

I solved this issue in Vue 3 with a composable:

/**
 * Reset the keyboard focus to the body tag on page changes.
 */
export const useRouterFocusReset = () => {
  onMounted(() => {
    const router = useRouter()
    router.afterEach((from, to) => {
      if(from.path !== to.path) {
        nextTick(() => {
          document.body.tabIndex = 0
          document.body.focus()
          document.body.tabIndex = -1
        })
      }
    })
  })
}

Then call it inside your main app component.

Lyokolux
  • 1,227
  • 2
  • 10
  • 34