Chromeでユーザースクリプトとして自作のショートカットキーを追加したかったのですが、色々ハマりポイントがあったのでメモ。
要件
- 元ページで定義されているショートカットキーに追加する形(元のショートカットキーも使えるようにする)
- 元ページで使われている関数や変数を自作スクリプト内で利用できる
が目標。
Chromeへのユーザースクリプトの追加の仕方
まずはChromeへのスクリプトの追加方法について。
- ユーザースクリプトを組む(***.js)
- マニフェストファイル(manifest.json)を記述
manifest.json
{ "manifest_version":2, // 2で固定 "version":"1.0", // スクリプトのバージョン "name": "スクリプト名", "content_scripts": [ { "js": ["***.js"], // スクリプトのファイル名 "matches": ["http://example.com/*"] // スクリプトを適応したいURLパターン } ] }
- 適当なディレクトリを作成し、上記2ファイルを入れる
- を表示し、作成したディレクトリをドラッグ&ドロップ
参考:
Chromeでユーザースクリプトを使う別の方法 - 公的内省
Chrome 拡張機能のマニフェストファイルの書き方 - Qiita
ショートカットキーを追加するスクリプトの組み方
冒頭で提示した要件
- 元ページで定義されているショートカットキーに追加する形(元のショートカットキーも使えるようにする)
- 元ページで使われている関数や変数を自作スクリプト内で利用できる
を満たす為に、
- イベントの追加にはaddEventListnerを使う
- スクリプトをDOMに挿入して動かす
事がポイントになります。
その点を踏まえて書いたスクリプトがこちら。
(function(callback) {
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
})(function(){
function canselEvent(e){
e.stopPropagation();
e.preventDefault();
return false;
}
document.addEventListener("keydown", function(e) {
switch(e.which){
case *: // *: キーコードを指定
hoge(fuga); // 処理を記述
canselEvent(e); // イベント伝播をキャンセル
break;
case *:
hogehoge();
canselEvent(e);
break;
/* 以下適宜追加 */
}
});
});
コードをざっくりと解説すると、
(function(callback) {
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
})(
// 省略
);
この部分は省略部分のコードをscript要素化してDOMに挿入するという作業を行っています。
これにより元ページのDOM構築が終わった後にスクリプトが読み込まれるので、自作スクリプト内で元ページで使われている関数・変数が利用可能になります。
function canselEvent(e){
e.stopPropagation();
e.preventDefault();
return false;
}
イベント伝播キャンセル用の関数を定義しています。
switch文の後にキャンセル処理を書いてしまうと、Chrome自体のショートカットキーが使えなくなってしまうため、
関数を用意してそれぞれのbreakの前に処理を行うようにしています。
document.addEventListener("keydown", function(e) {
switch(e.which){
case *: // *: キーコードを指定
hoge(fuga); // 処理を記述
canselEvent(e); // イベント伝播をキャンセル
break;
case *:
hogehoge();
canselEvent(e);
break;
/* 以下適宜追加 */
}
});
keydownイベントリスナーを追加し、自作ショートカットキーを定義します。
ChromeではKeyboardEvent.whichで押されたキーコードを取得できるので、switchに渡して分岐。
ちなみに、Chrome以外ではKeyboardEvent.KeyCodeだったりします。
クロスブラウザ対応したい場合には、
(window.event) ? e.keyCode : e.which
みたいにしてやると良いみたいです。
各キーコードごとにcase文に処理を書き、最後にイベント伝播をキャンセルしてbreak。
まとめ
- イベントの追加にはaddEventListnerを使う
- スクリプトをDOMに挿入して動かす
- Chromeでのキーコードの取得はKeyboardEvent.whichを使う
それにしても、キーイベントを取得したい事なんて山程あるだろうに、未だ仕様が固まっていないってどういう事なんですかね…。