LoginSignup
0
0

More than 3 years have passed since last update.

focusイベントがキャンセルできない問題。

Last updated at Posted at 2020-01-15

Vueを触っている時、ブラウザを切り替えたタイミングでフォーカスを外したいコンポーネントにあうことはありませんか?
そんな時まず思い浮かぶのは、eventをpreventDefaultすることだと思います。
事実、私もそう思い実行しました。
しかし、うまくいきませんでした。
なぜ?調べてみました。

focusイベントについて

MDNを見てみる。

focus イベントは、要素がフォーカスを受け取ったときに発生します。このイベントと focusin との違いは、 focusin がバブリングを行うのに対し focus は行わないことです。
focus の反対は blur です。

バブリング なし
キャンセル可能 いいえ

キャンセル不可のため、preventDefalutは効かないらしい・・・。
というこで、フォーカスを発生させないためには逆にフォーカスを外してやればいい。
まぁそういえばそうかといった感じですが・・・

正解コード(javascript)

el-tooltipはコンポーネント内のフォーカスを外したい要素のクラス名です。

App.js
  mounted() {
    window.addEventListener("focus", () => {
      const onFocutElm = window.document.activeElement;
      if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
        onFocutElm.blur();
      }
    });
  }

正解コード(typescript)

App.ts
  mounted() {
    window.addEventListener("focus", () => {
      const onFocutElm = window.document.activeElement;
      if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
        (onFocutElm as HTMLElement).blur()
      }
    });
  }

おまけ

上記コードではフォーカスを外すことができましたが、 Firefixブラウザではなぜかうまくいきませんでした。
その為、setTimeoutを挟むことで正しく処理されました。

App.js
  mounted() {
    window.addEventListener("focus", () => {
      setTimeout(() => {
        const onFocutElm = window.document.activeElement;
        if (onFocutElm && onFocutElm.classList.contains("el-tooltip")) {
          onFocutElm.blur();
        }
      }, 0);
    });
  }

また、単にフォーカスを要素から外したいのであればbody自体にフォーカスを当てる方法もあります。
divなどの要素にフォーカスを当てるにはtabindex属性をセットする必要があります。

App.js
  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();
      }
    });
  }
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0