Vue: Autofocus is lost once vue is loaded

Created on 1 May 2018  ·  16Comments  ·  Source: vuejs/vue

Version

2.5.16

Reproduction link

https://jsfiddle.net/alfonsobries/u83vkLe1/

Steps to reproduce

When you add the autofocus attribute to an input it will be focused once is loaded, but when you init a Vue app the focus is lost so you need to manual focus an element

In this second link (witouth Vue the autofocus works)
Autofocus not lost

What is expected?

That an input keep focused if has the autofocus attribute

What is actually happening?

the focus is lost


Its possible to emulate this behaviour but i think it should work witouth need to "emulate" the behaivour

browser quirks

Most helpful comment

easier workaround is just add vue attribute :autofocus="'autofocus'"

All 16 comments

Either use v-cloak or a separate template.

Thank @KaelWD ! v-cloak is a good workaround. https://stackoverflow.com/questions/9122527/will-focus-be-set-to-invisible-form-controls-using-html5-autofocus

On the other hand, I wonder if it is worth a special handling for autofocus in core, though this problem might also occur in SSR. You can, nevertheless, write your own directive like v-autofocus to focus on input when it is hydrated.

I tried to fix this with no luck. I think this is a similar issue https://github.com/lovelope/vue/commit/8109e44577e49524da83139287d54b2bc83ac2a1 but trying to fix it with the same idea won't work since muted and autofocus works differently by nature.

Since autofocus runs only when the page loads I think the solution must be calling .focus() on the element after the component is mounted but I didn't find where I should do this implementation.

I can use a little guidance here if possible.

The other workaround is to simply avoid using in-dom templates, and use string templates or pre-compiled templates instead. https://jsfiddle.net/3gd0bLk5/

easier workaround is just add vue attribute :autofocus="'autofocus'"

I'm using VueJS with Laravel and I also noticed this problem. I'm in a PHP environment so "avoid using in-dom templates" is not an acceptable solution. :autofocus="'autofocus'" and v-focus is working but if we could avoid using VueJS for these kind of HTML5 things it's better :-)

I suppose you can use <script type="x-template"> in PHP? That is also a valid workaround and isn't "in-dom" template.

using :autofocus="'autofocus'" makes the html a mess

@ThibaudDauce same thing here, I'm working with Laravel and some parts of my views (which contains autofocus) are not part of Vuejs.

v-cloak trick works on Chrome but not on Firefox. I ended up doing this:

const app = new Vue({
    el: '#app',
    mounted() {
        let input = document.querySelector('[autofocus]');
        if (input) {
            input.focus()
        }
    }
});

I made a fiddle but it seems to be a bug and it doesn't work on Firefox either, but the code does: http://jsfiddle.net/azeos/quwLfj9c/

Thanks for the suggestions in this

@ThibaudDauce same thing here, I'm working with Laravel and some parts of my views (which contains autofocus) are not part of Vuejs.

v-cloak trick works on Chrome but not on Firefox. I ended up doing this:

const app = new Vue({
    el: '#app',
    mounted() {
        let input = document.querySelector('[autofocus]');
        if (input) {
            input.focus()
        }
    }
});

I made a fiddle but it seems to be a bug and it doesn't work on Firefox either, but the code does: http://jsfiddle.net/azeos/quwLfj9c/

this will work in firefox if you replace this html
<input type="text" autofocus> with <input type="text" :autofocus="'autofocus'">

You could also use native javascript

<div id="app">
  <input type="text" name="name" id="myname">
  <input type="text" name="email">
</div>
<script>
new Vue({
  el: "#app",
  methods:{
    formfocus() {
      document.getElementById("myname").focus();
    }
  },
  mounted(){
    this.formfocus()
  }
})
</script>

checkout the code here https://jsfiddle.net/w5f1teu0/
Any more questions? check me out here https://marcus-hiles.com/ and lets connect.

@marcus-hiles My application uses a barcode scanner gun and I have a function that directs the gun to do whatever I instruct it to do after they read as well as destroy it after reading it. Your autofocus solution along with @azeos works perfectly, but I was wondering if this can be setup to move the focus once the input field with initial focus has content in it. So that I can keep scanning without tabbing or using the mouse. Which event should I use? And this call for a nextTick? FOr example:

moveFocus() {
    nextTick autofocus to the next item
}

and add moveFocus as a blur event?

<input @blur="moveFocus" :autofocus="'autofocus'"/>

Damn... This is weird! I wasted too much time. I should have checked GitHub first.

Why not adding a directive like v-focus (see e.g. accepted answer from this Stackoverflow question) as standard built-in in vuejs?

Easy enough to use a ref and focus() it on mounted, but Vue should support this natively to meet developer expectations and to respect HTML. In addition to page load, I've noticed browsers will focus Custom Elements that have this attribute and Riot.js also supports this attribute w/o requiring anything from the developer. Native Vue support would be much appreciated!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bdedardel picture bdedardel  ·  3Comments

6pm picture 6pm  ·  3Comments

bfis picture bfis  ·  3Comments

seemsindie picture seemsindie  ·  3Comments

lmnsg picture lmnsg  ·  3Comments