【Tampermonkey】特定サイトのショートカットキーを無効化/任意のスクリプト実行を行う方法

# 概要

Chrome拡張機能のTampermonkeyを使用して特定サイトでのショートカットキーを無効化したり、
任意のスクリプトを実行する方法を紹介します。

# 導入のきっかけ

普段 [Notion](https://www.notion.so/ja-jp/product) を使ってメモしているのですが、
`Ctrl + E`が Markdownのコードスパン(` ``で囲むやつ `)的に使えるので多用します。

しかし`E`キーの隣りにある`R`を間違って押して`Ctrl + R`とするとブラウザリロードをしてしまい、入力中に(入力内容が消えてしまうことはなくとも)ブラウザの更新となり、メモの妨げになってしまうため、無効化したいと思ったため。

ただ、Notion利用中だけ無効化したい(他のサイトでは無効化したくない)としたかったため、
[Disable keyboard shortcuts](https://chrome.google.com/webstore/detail/disable-keyboard-shortcut/aidbmcboeighgdnilpdljbedbbiocphj) のようなブラウザ自体のショートカットキーを無効化するものは使用したくなかった。

# 使用するもの

Chrome拡張機能のTampermonkey (Chrome以外もありますがChromeのみリンク記載します)

https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja

## ドキュメント

Tampermonkeyのドキュメントは以下をご参照ください

https://www.tampermonkey.net/documentation.php

# 設定

拡張機能の欄からTampermonkeyのアイコンクリック > 新規スクリプトを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/8dcb4785-c1ee-aecb-1f0a-2b9c19a76ad4.png)

エディタが開かれ、雛形が表示されるのでその中身をいじっていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/32dfc8de-d2f5-c78f-b717-b00649ab1fe3.png)


## とりあえず動作確認

とりあえずの動作確認としてwindowのロードタイミングでalertを出すスクリプトに変更します。

```js
// ==UserScript==
// @name         Hello World
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://qiita.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=qiita.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    window.addEventListener('load', function() {
        alert('Hello World');
    });
})();
```

`// @match        https://qiita.com/*` の部分で正規表現でマッチするサイトのみこのスクリプトが実行されるように設定ができます。
※この部分は`新規スクリプトを追加`を行ったときに開いていたページが設定されています。

アラートが表示できることを確認できたら、スクリプトを変更していきます。

## 本題のショートカットキーの上書き

何の変哲もない入力抑止のスクリプトを仕込むことでショートカットキーを無効化します。

```js
(function() {
    'use strict';

    document.body.addEventListener('keydown', function(e) {
        if (e.ctrlKey && e.key === 'r') {
            e.preventDefault();
        }
    });
})();
```

## ちょっと改良

ただ無効化しただけだとなんで効かなくなったかわからなくなるかもしれないので、トースト表示が行われるようにします。私はjQueryのtoastrが好きなのでそちらを使用します。

https://codeseven.github.io/toastr/


```js
// ==UserScript==
// @name         Notion Reload Shortcut Disabled
// @namespace    http://tampermonkey.net/
// @description  NotionのCtrl+Rのブラウザリロードを無効化する
// @version      0.1
// @author       You
// @match        https://www.notion.so/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=notion.so
// @resource     toastr.min.css https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js
// @grant        GM_addStyle
// @grant        GM_getResourceText
// ==/UserScript==

(function() {
    'use strict';

    const newCSS = GM_getResourceText("toastr.min.css");
    GM_addStyle(newCSS);

    document.body.addEventListener('keydown', function(e) {
        if (e.ctrlKey && e.key === 'r') {
            toastr.warning("Ctrl + R は Tampermonkey で無効化");
            e.preventDefault();
        }
    });
})();
```


ポイントとしては以下の箇所でtoastrを使用するためにjQuery、toastr自身、toastrのCSSを読み込みと権限を与える必要があることと

```js
// @resource     toastr.min.css https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js
// @grant        GM_addStyle
// @grant        GM_getResourceText
```

また、先頭の方で以下のようにすることでCSSの読み込み(実際にはheadタグ内にstyleタグが埋め込まれるようです)を行います。

```js
const newCSS = GM_getResourceText("toastr.min.css");
GM_addStyle(newCSS);
```

CSSやjavascriptの読み込みに関しての参考元: [GreasemonkeyやTampermonkeyで外部CSSを読み込む](https://yamap55.hatenablog.com/entry/2019/07/08/171038)

↓動作的にはこんな感じ(`Ctrl + Shift + R`は通常動作(スーパーリロード)のままとなっています)
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/d12b38a0-5662-eba3-d744-e012d8d790db.gif)


(toastrの読み込み部分までを雛形的に使うといいかもしれませんね)

## スクリプトの管理

`インストール済みUserScript`のタブでスクリプトの有効/無効を変更できます。
(一時的にスクリプトを無効化したいとき等は`有効`の列のトグルを切り替えることで変更できます。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/b143850e-f206-2ad3-d5ca-7b5c8085c929.png)


# 終わりに

今回は特定サイトで特定キーの無効化(ブラウザリロードを無効化)を行いましたが、スクリプトを書くことさえできれば任意のスクリプトを実行できるので有効活用していきたいですね！