俵のメモ帳

メモ帳です。このブログに書き残すコードはパブリックドメインとして扱います。

ブラウザ「Vivaldi」で、Ctrl+Tabが利かないサイトが気になったときの対処

Vivaldi ver 7.2 で、ショートカットキーの優先度設定ができるようになったため、こちらに記載する対策はアプリケーション自前で行えるようになりました。よって、本記事の対策は非推奨としました。

Vivaldi、なんかCtrl+Tabが利かない瞬間がある…?

ブラウザの Vivaldi を愛用していると時々遭遇する問題。それが「Ctrl+Tabでタブ切り替えできなくなるWebサイトがある問題」です。

例えば、最近見つけたところだと 寿司打 (2024-10-20 時点) のページで発生します。

原因

「Webサイト側のJavaScriptにて、ショートカットキーで使われているのと同じキーでのkeydownイベントにより event.preventDefault() が呼び出されると、対象ショートカットキーの動作がキャンセルされる」というVivaldiの仕様に起因するようです。

これは、2018年に報告されている keydown イベントのキャンセルでタブとウィンドウの操作を無効化できてしまう | Vivaldi Forum でも触れられています。これだけ昔からこの動作ということは、Vivaldiとしては不具合ではなく適切な仕様という扱いなのでしょうね。

つまりVivaldiでのCtrl+Tabキーが動作しなくなる問題は、JavaScriptでTabキーの押下イベント時に event.preventDefault() を実行し、デフォルト動作をキャンセルしているWebサイトで起こり得ます。

Tabキー動作無効化をWebサイト側で実装する背景としては、何らかの理由でTabキーによる要素のフォーカス移動を抑制したいケースが考えられます。例えば前述の寿司打のようなブラウザゲームの場合、プレイ中にTabキーによるフォーカス移動が発動すると困るでしょうから、そういった理由からTabキー押下イベントを意図的に無効化するのも分かります。

さて、上記を踏まえると、以下のようなHTMLで、Ctrl+Tabが動作しなくなることを再現できます。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>
    // Tabキーを押した際のイベントをキャンセルする
    window.addEventListener('keydown', function(e) {
      if (e.key === 'Tab') {
        const div = document.createElement('div');
        div.textContent = 'Tab key pressed';
        document.getElementById('pressed').appendChild(div);
        // デフォルトの動作をキャンセル
        e.preventDefault();
      }
    });
  </script>
</head>
<body>
  <div id="pressed"></div>
</body>
</html>

回避策

前述の通り、 event.preventDefault() がWebサイト側で実行されなければ良さそうだと当たりがつきました。なおかつ、「Ctrl+Tabキー、Ctrl+Shift+Tabキーでは event.preventDefault() が発動しないようにして、Tabキー単体やShift+TabではWebサイト側の実装のまま」といった状況にできればよさそうです。ということで、Chrome拡張 Tempermonkey を利用して、これを実現していきます。

Tempermonkeyを利用すると、任意のJavaScriptを適当なサイトで実行することができるので、これを利用してVivaldiのショートカットキーがちゃんと動くようにキー押下イベントを調整します。

(1) TempermonkeyでUserScriptを新規作成

Tempermonkey UserScript新規作成

(2) UserScriptエディターに、以下のJavaScriptを貼り付ける

// ==UserScript==
// @name         fix vivaldi shortcut events
// @namespace    http://tampermonkey.net/
// @version      2025-02-25
// @description  VivaldiのショートカットキーがWebサイトのJavaScriptによってキャンセルされないようにする
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function stopEvent(e) {
        if (e.ctrlKey) {
            if (e.key == "Tab"
                || e.key == "PageUp"
                || e.key == "PageDown"
            ) {
                e.stopImmediatePropagation();
            }
        }
    }

    window.addEventListener('keydown', stopEvent, true);

    document.addEventListener('keydown', stopEvent, true);

    // document.addEventListener の指定だけで十分かも?以下コメントアウトして様子見する
    // document.querySelectorAll('textarea, input').forEach(function (e) {
    //     e.addEventListener('keydown', stopEvent, true);
    // });
})();

(3) Ctrl+Tabの操作がうまくいかないWebサイトで、動作するようになったかを確認する

まとめ

こういったVivaldiの動作そのものは、Webサイト側で定義したキーイベントを阻害しないようにと意識をした仕様と思われますが、Ctrl+Tabのようなブラウザの挙動を最優先したいケースにおいては困りますね…。

地味に不便だったので、回避策が見出だせたのは幸いでした。