キーボード入力をスクリプトに代行させる
ブラウザ上で実行されるアプリ(アメブロの編集画面や管理画面等)に対して、「キー入力した」と同等の事を代行させることが 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 を生成する書式
上例は、単純に「↓」を押すイベントを生成して変数「KEvent」に代入しています。
実際に試すと、私の環境では下の様に不要なイベント属性を省略できました。
結局「keyCode: 40」だけが必要不可欠で、「Shift」等の同時押しがない場合は省略しても構わない様です。(Shiftキー等の同時押しの生成は未テストです)
KeyboardEvent を送出する書式
「KeyboardEvent」を生成しただけでは何も起こりません。 これを「送出」する関数「dispatchEvent」を実行する事で、実際にページ上に入力を代行できます。
「送出」は送込む対象が必要です。 一般的に「document」を対象とする事も出来ますが、対象要素(Element)の指定がないと思い通りにならない事が多いです。
以下の書式は、先に作った変数「KEvent」のキー内容を「送出」する完成形です。
〔 一般的に document を対象とした書式 〕
〔 特定の要素を対象とした書式 〕
これで、キーイベントがスクリプトにより実行されます。
以上の2つの書式は、見通しを良くするため変数「KEvent」を使っていますが、下の様に直接に繋げて書いても同じ結果です。
〔 一般的に document を対象とした書式 〕
〔 特定の要素を対象とした書式 〕
CSSセレクタで対象要素を特定する書式
ここまでの、対象の要素を指定する「.getElementById(" 対象のid名 ")」の部分は、CSSセレクタの書式を使って「.querySelector(" 対象のセレクタ記述 ")」で置き換える事が出来ます。
〔 CSSセレクタで特定した要素を対象とした書式 〕
但し「 .querySelector() 」の書式のカッコ内は、セレクタ記述の形が必須です。
◎「id名」を使う場合は「"# id名"」、「class名」を使う場合は「". class名"」といった書き方になるので注意が必要。
◎ class名が複数の対象を指す場合は、「.querySelectorAll(".class名") [0] 」といった様に配列の順番の指定が必要で、これが無いと無効になります。
◎ セレクタ記述で「".class > div"」は有効ですが「"> div"」は使えない様です。 少し特殊なセレクタ指定は、目的要素を正しく取得出来ているかテストが必要です。
keyCord 番号・対象のセレクタ を入力すれば使える関数
CSSセレクタで特定した要素を対象とした書式の変形ですが、下の関数「key_in()」を「対象のCSSセレクタ記述」の部分を設定してスクリプト中に登録しておくと、後は必要な「keyCord」を引数で指定して、複数の場所で複数文字の入力に使えます。
例えば「↓」を入力させたい時は、「 key_in(40); 」と書くだけで対象に入力が実行されます。 複数のキー入力を繰り返す場合は、こういう関数化が便利です。
キーボード入力の代行が上手く働かない場合
少なくとも現在の Chrome上では、JavaScript だけで充分にキー入力のイベントの実行が可能な様です。 もし思い通り働かない場合は、以下の点を試してみてください。
◎ 最初から「Shift」同時押しなどの入力を試さず、単純な「 a 」等の文字で試し、上手く行ったら、同時押しのコードも試す。
◎ 上例では「 keyCode: 40 」で動作しましたが、紛らわしい設定が多数考えられます。 ネット上には、旧いIEなどを前提にしたコードも多く、それらと混同し易い。
「 key: "ArrowDown" 」「 key: "Down"」「 key: 40 」などは全て無効で、総当たりで書き方を変えて、動く指定を探すつもりで諦めないこと。
◎ イベントの送出対象の指定を間違っていて、入力されない事があるのも考慮する。 送出対象の指定がとても厳密で、対象の親要素や子要素は駄目という事も普通です。
◎ イベントの送出対象にフォーカスが無いと入力されない場合があります。 キー入力の対象が「element」とすると、コードの直前に「 element:focus(); 」を入れると入力が可能になった事があります。
◎ 私自身の経験では、どういう方策を尽くしても機能しない場合はあります。 そのコードが対象とする入力要素や、その背景に働くスクリプト等に関係するのかも知れません。 ユーザースクリプトでの代行入力は、必ず動作する保証はない様です。