Vue: How to call .focus() on button click
Finally solved the problem without setTimeout
, thanks to window.requestAnimationFrame
(I don't know why):
startTimer () {
window.requestAnimationFrame(() => this.$refs.typeBox.focus())
}
It works even for custom component focusing.
Sharing the solution here just in case someone encounters the same problem...
I finally figured this out with the help of a senior programmer. I was also able to eliminate setTimeout
along the way, using its vue
version nextTick()
.
The correct JS code:
startTimer () {
this.$nextTick(() => {
// this won't work because `this.$refs.typeBox` returns an array
// this.$refs.typeBox.focus()
//this one works perfectly
this.$refs.typeBox[0].focus()
})
} /* END startTimer */
Explanation:
When I used console.log(this.$refs.typeBox)
, it returned this array:
That's why for the code to work, it had to be typeBox[0].focus()
instead of typeBox.focus()
.
The value of this
in the setTimeout
function will be set to window
object since it is callback function executing after a period of time and it had lost the scope of this
keyword which is dynamically set from where the function is being called.
Arrow functions doesn't bind it's own value of this
.
startTimer () {
setTimeout(() => {
this.$refs.typeBox.focus()
}, 1)
}
OR
startTimer () {
const self = this;
setTimeout(function () {
self.$refs.typeBox.focus()
}, 1)
}