キーボード入力をスクリプトに代行させる

ブラウザ上で実行されるアプリ(アメブロの編集画面や管理画面等)に対して、「キー入力した」と同等の事を代行させることが JavaScriptでは可能です。 スクリプトのプログラムは、ユーザーのブラウザ上の殆どの操作を、代行する事が可能と思われます。 悪用すれば危険な仕様と誰も想像出来ますが、実際にその様です。

 

しかし、ネットに多くの情報がありますが、半分以上の情報は「使えない」という壁に当たりました。 そこには、旧いIEの仕様の問題や、Firefox Chrome等と仕様が異なる問題、ハードウエアに関連する問題など、JavaScriptのコードが統一出来ず現在に至った背景がある様です。

 

この問題と、私のコードの扱いの不慣れが重なり、なかなか実際にキー入力が実現せずに苦労しました。 ここでは、「Chrome」と「Tampermonkey」の環境で、入力を代行させる JavaScriptコードを整理しておきます。 もし、そんな必要がある方には、役にたつかも知れません。

 

 

 

キーボード入力の代行には「KeyboardEvent」「dispatchEvent」が必要

キー入力に反応して何かをする場合は「キーイベントの取得」が必要です。 この説明は良くあり、再現性は良いのですが、スクリプトから「キー入力を代行させる」には「キーイベントの発行」が必要で、その説明は少なくて不統一です。

 

先ず、キーイベントは JavaScriptでは「KeyboardEvent」として扱います。「発行」操作にはこのオブジェクトを「生成」した上で「送出」する必要があります。 この送出には「dispatchEvent」関数を使います。

 

KeyboardEvent とそのオプション

「KeyboardEvent」のイベントには「keydown」「keypress」「keyup」の 3つがあり、「発行」には一般に「keydown」(押した)「keyup」(押したのを離した)のどちらかを使う。(「keypress」は非推奨です )

 

これらのイベントは多くの属性があり、実際はどんなキーをどういう押し方をしたとか、Shiftキーと一緒に押したとかを、その属性で指定する。

 

実際に「発行」で必要なのは、

 

keyCode:」 押されたキーのキーコード番号 (Enter: 13 、Down:40 など)

               keyCode 番号テスト:w3.org / Keyboard Event Properties

「altKey:」 Alt の同時押しは true 、そうでなければ false

「shiftKey:」 Shift の同時押しは true 、そうでなければ false

「ctrlKey:」 Ctrl の同時押しは true 、そうでなければ false

「key:」  押されたキーのキー名 ( "Enter" や"ArrowDown" など)

               key 名テスト: MDN KeyboardEvent.key

 

  他にも多くの属性が有りますが、「生成」で使うのは上で充分でしょう。

 

KeyboardEvent を生成する書式

let KEvent = new KeyboardEvent( "keydown", { keyCode: 40, altKey: false, shiftKey: false, key: "ArrowDown" });

 

上例は、単純に「↓」を押すイベントを生成して変数「KEvent」に代入しています。

実際に試すと、私の環境では下の様に不要なイベント属性を省略できました。 

 

let KEvent = new KeyboardEvent( "keydown", { keyCode: 40 });

 

結局「keyCode: 40」だけが必要不可欠で、「Shift」等の同時押しがない場合は省略しても構わない様です。(Shiftキー等の同時押しの生成は未テストです)

 

KeyboardEvent を送出する書式

「KeyboardEvent」を生成しただけでは何も起こりません。 これを「送出」する関数「dispatchEvent」を実行する事で、実際にページ上に入力を代行できます。

 

「送出」は送込む対象が必要です。 一般的に「document」を対象とする事も出来ますが、対象要素(Element)の指定がないと思い通りにならない事が多いです。

 

以下の書式は、先に作った変数「KEvent」のキー内容を「送出」する完成形です。

 

〔 一般的に document を対象とした書式 〕

let KEvent = new KeyboardEvent( "keydown", { keyCode: 40 });
document.dispatchEvent( KEvent );

 

〔 特定の要素を対象とした書式 〕

let KEvent = new KeyboardEvent( "keydown", { keyCode: 40 });
document.getElementById(" 対象のid名 ").dispatchEvent( KEvent );

 

これで、キーイベントがスクリプトにより実行されます。

 

以上の2つの書式は、見通しを良くするため変数「KEvent」を使っていますが、下の様に直接に繋げて書いても同じ結果です。

 

〔 一般的に document を対象とした書式 〕

document.dispatchEvent( new KeyboardEvent( "keydown", { keyCode: 40 }));

 

〔 特定の要素を対象とした書式 〕

document.getElementById(" 対象のid名 ").dispatchEvent( new KeyboardEvent( "keydown", { keyCode: 40 }));

 

CSSセレクタで対象要素を特定する書式

ここまでの、対象の要素を指定する「.getElementById(" 対象のid名 ")」の部分は、CSSセレクタの書式を使って「.querySelector(" 対象のセレクタ記述 ")」で置き換える事が出来ます。

 

〔 CSSセレクタで特定した要素を対象とした書式 〕

document.querySelector(" 対象のCSSセレクタ記述 ").dispatchEvent( new KeyboardEvent( "keydown", { keyCode: 40 }));

 

但し「 .querySelector() 」の書式のカッコ内は、セレクタ記述の形が必須です。

 

◎「id名」を使う場合は「"id名"」、「class名」を使う場合は「". class名"」といった書き方になるので注意が必要。

 

◎ class名が複数の対象を指す場合は、「.querySelectorAll(".class名") [0] 」といった様に配列の順番の指定が必要で、これが無いと無効になります。

 

◎ セレクタ記述で「".class > div"」は有効ですが「"> div"」は使えない様です。 少し特殊なセレクタ指定は、目的要素を正しく取得出来ているかテストが必要です。

 

keyCord 番号・対象のセレクタ を入力すれば使える関数

CSSセレクタで特定した要素を対象とした書式の変形ですが、下の関数「key_in()」を「対象のCSSセレクタ記述」の部分を設定してスクリプト中に登録しておくと、後は必要な「keyCord」を引数で指定して、複数の場所で複数文字の入力に使えます。

 

function key_in( key_Code ) {
document.querySelector("対象のCSSセレクタ記述").dispatchEvent( new KeyboardEvent("keydown", { keyCode: key_Code })); }

 

例えば「↓」を入力させたい時は、「 key_in(40); 」と書くだけで対象に入力が実行されます。 複数のキー入力を繰り返す場合は、こういう関数化が便利です。

 

 

キーボード入力の代行が上手く働かない場合

少なくとも現在の Chrome上では、JavaScript だけで充分にキー入力のイベントの実行が可能な様です。 もし思い通り働かない場合は、以下の点を試してみてください。

 

◎ 最初から「Shift」同時押しなどの入力を試さず、単純な「 a 」等の文字で試し、上手く行ったら、同時押しのコードも試す。

 

◎ 上例では「 keyCode: 40 」で動作しましたが、紛らわしい設定が多数考えられます。 ネット上には、旧いIEなどを前提にしたコードも多く、それらと混同し易い。

「 key: "ArrowDown" 」「 key: "Down"」「 key: 40 」などは全て無効で、総当たりで書き方を変えて、動く指定を探すつもりで諦めないこと。

 

◎ イベントの送出対象の指定を間違っていて、入力されない事があるのも考慮する。 送出対象の指定がとても厳密で、対象の親要素や子要素は駄目という事も普通です。

 

◎ イベントの送出対象にフォーカスが無いと入力されない場合があります。 キー入力の対象が「element」とすると、コードの直前に「 element:focus(); 」を入れると入力が可能になった事があります。

 

◎ 私自身の経験では、どういう方策を尽くしても機能しない場合はあります。 そのコードが対象とする入力要素や、その背景に働くスクリプト等に関係するのかも知れません。 ユーザースクリプトでの代行入力は、必ず動作する保証はない様です。