昨日は_vue.js
_でコーディングを始めたばかりで、「従来の」JSの方法であるdocument.getElementById('myTextBox').focus()
を使用せずにテキストボックスに「焦点を合わせる」方法がわかりません。
最初、私のテキストボックスは非表示になっています。 「スタート」ボタンがあり、ユーザーがそれをクリックすると、テキストボックスが表示されます。いわば、そこにfocus
を設定したいと思います。私はすでにref
を使用しようとしましたが、役に立ちませんでした(以下のコードを参照)。
HTML:
_<input id="typeBox" ref="typeBox" placeholder="Type here..." />
_
Javascript
_export default {
name: 'game',
methods: {
startTimer () {
setTimeout(function () { /* .focus() won't work without this */
/* ugly and not recommended */
// document.getElementById('typeBox').focus()
/* Throws the error: Cannot read property 'typeBox' of undefined */
this.$refs.typeBox.focus()
// ... any other options?
// ...
}, 1)
}
} /* END methods */
} /* END export default */
_
誰かがこれを行う方法を知っていますか?助けてください。
更新:
autofocus
にinput
を追加すると、ページが読み込まれた直後にフォーカスを合わせるというトリックが実行されます。しかし、私のアプリでは、ページをリロードせずに入力フィールドに数回「リフォーカス」する必要があるため、.focus()
を呼び出す方法が必要です。
誰かが同じ問題に遭遇した場合に備えて、ここで解決策を共有します...
私はついに上級プログラマーの助けを借りてこれを理解しました。また、setTimeout
バージョンnextTick()
を使用して、途中でvue
を削除することもできました。
正しいJSコード:
_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 */
_
説明:
console.log(this.$refs.typeBox)
を使用すると、次の配列が返されました。
そのため、コードが機能するには、typeBox[0].focus()
ではなくtypeBox.focus()
である必要がありました。
this
関数のsetTimeout
の値は、一定期間後に実行されるコールバック関数であり、関数が呼び出されている場所から動的に設定されるwindow
キーワードのスコープを失ったため、this
オブジェクトに設定されます。
矢印関数は、それ自体の値this
をバインドしません。
startTimer () {
setTimeout(() => {
this.$refs.typeBox.focus()
}, 1)
}
OR
startTimer () {
const self = this;
setTimeout(function () {
self.$refs.typeBox.focus()
}, 1)
}
window.requestAnimationFrame
のおかげで、setTimeout
なしで問題を最終的に解決しました(理由はわかりません):
startTimer () {
window.requestAnimationFrame(() => this.$refs.typeBox.focus())
}
カスタムコンポーネントのフォーカシングでも機能します。