Vueを触っている時、ブラウザを切り替えたタイミングでフォーカスを外したいコンポーネントにあうことはありませんか?
そんな時まず思い浮かぶのは、eventをpreventDefaultすることだと思います。
事実、私もそう思い実行しました。
しかし、うまくいきませんでした。
なぜ?調べてみました。
focusイベントについて
MDNを見てみる。
focus イベントは、要素がフォーカスを受け取ったときに発生します。このイベントと focusin との違いは、 focusin がバブリングを行うのに対し focus は行わないことです。
focus の反対は blur です。
| バブリング | なし |
|:--|:--|
| キャンセル可能 | いいえ |
キャンセル不可のため、preventDefalutは効かないらしい・・・。
というこで、フォーカスを発生させないためには逆にフォーカスを外してやればいい。
まぁそういえばそうかといった感じですが・・・
正解コード(javascript)
el-tooltipはコンポーネント内のフォーカスを外したい要素のクラス名です。
mounted() {
window.addEventListener("focus", () => {
const onFocutElm = window.document.activeElement;
if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
onFocutElm.blur();
}
});
}
正解コード(typescript)
mounted() {
window.addEventListener("focus", () => {
const onFocutElm = window.document.activeElement;
if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
(onFocutElm as HTMLElement).blur()
}
});
}
おまけ
上記コードではフォーカスを外すことができましたが、 Firefixブラウザではなぜかうまくいきませんでした。
その為、setTimeoutを挟むことで正しく処理されました。
mounted() {
window.addEventListener("focus", () => {
setTimeout(() => {
const onFocutElm = window.document.activeElement;
if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
onFocutElm.blur();
}
}, 0);
});
}
また、単にフォーカスを要素から外したいのであればbody自体にフォーカスを当てる方法もあります。
divなどの要素にフォーカスを当てるにはtabindex属性をセットする必要があります。
mounted() {
window.addEventListener("focus", () => {
const onFocutElm = window.document.activeElement;
if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
const body = document.body;
body.tabIndex = 0;
body.focus();
}
});
}