概要
何らかの処理をした際に、Elementに動的にフォーカスを当てたいことがある。
筆者の例では、一部のDOMをv-ifで表示制御しており、Boolean型で開閉を変える時に動的フォーカスを当てたかった。
検索した結果Element.focus()を使えば期待した動作をすることがわかったが、querySelectorからElementを取得した場合開発環境のNuxt.jsでは動かなかった。
それに関して少し調べたのでわかる範囲で走り書きしておく。
querySelectorで動かなかった原因
Document.querySelector() - Web API | MDN
querySelectorではElementが取得できるが、focus()メソッドが存在するのはHTMLElementだったからでした。
HTMLElementはElementを継承しているし名前が似ているため、少しわかりにくいですね。
refsから取得すると、HTMLInputElementが取得できました。__proto__を見る限り、こちらはHTMLElementを継承しているっぽいです。
Element → HTMLElement → HTMLInputElement
って流れですね!
動かないコード
<template>
<div>
<input type="text" class="text-input">
</div>
</template>
// not work
document.querySelector('.text-input').focus();
動くコード
<template>
<div>
<input type="text" ref="textInput" class="text-input">
</div>
</template>
this.$refs.textInput.focus();
また、DOMがレンダリングされてからフォーカスしたい際は this.$nextTick
を利用する必要があるのでこちらもセットで使うとなおよし。
this.$nextTick(() => this.$refs.textInput.focus());
参考リンク
Element - Web API | MDN
HTMLElement - Web API | MDN
How to set focus() to input? - Get Help - Vue Forum