React を使った テキストボックスやセレクトボックスに Bookmarklet で自動入力させる
Bookmarklet とは
-
ブックマークの URL に登録して使う、javascript のプログラム
-
アラートを出したり入力欄に自動入力したり、いろいろできる
-
コードには以下の特徴がある
- 先頭に
javascript:
をつける - コードは一行だけ
- 先頭に
-
例)以下のコードをブックマークの URL に登録し、ブックマークをクリックすると、
Hello Bookmarklet
とアラートが表示される
javascript: alert('Hello Bookmarklet')
経緯
開発やテストの時は名前などを入力フォームに何百回も入力する(よね?)。今まで手入力だったので、ボタン一つで入力できるようにしようと考えた
しかし Vanilla JS なら簡単だが、React はひと手間増えるようだった。そこで詰まったので備忘録をかねて投稿する
作成手順(Vanilla JS)
普通の javascript なら簡単にできる。
コード作成
- 以下のコードを作成する
(function () {
const name = document.getElementById("name");
name.value = "山田";
})();
コンパイル
Closure Compilerでコードをコンパイルする。一行にまとめてくれるだけでなく、不要な空白を消したりエンコードしたりして最適化してくれる
-
左の枠にコードを入力し、
Compile
ボタンを押す -
成功すると右の枠にコードが出てくる
(function(){document.getElementById("name").value="\u5c71\u7530"})();
コード登録
-
コードの先頭に
javascript:
をつけて、ブラウザのブックマークにコードを登録するjavascript:(function(){document.getElementById("name").value="\u5c71\u7530"})();
-
入力欄があるところでブックマークをクリックすると、「山田」が自動入力される
サンプルを用意したのでお試しあれ
※Bookmarkletはたいていブックマークに登録して使うが、サンプルのように<a>
タグのhref
属性に指定して使うこともできる
作成手順(React・テキストボックス)
Reactで同じことをするとうまくいかない。下のサンプルを見てほしい。
テキストボックスにキーボードで何か入力すると、下段の値(state)にも反映される。一方Bookmarkletを使った場合、テキストボックスには反映されるが、下段に変化はない。詳しいことまでは分かっていないが、今までのBookmarkletでは表面上値を変更できても、内部の値は変更できないようだ。
コードを少し変える
(function () {
const name = document.getElementById("name");
name.value = "山田";
+ name._valueTracker.setValue("");
+ name.dispatchEvent(new Event("input", { bubbles: true }));
})();
-
_valueTracker
は最終手段?のようなもので、あまり使うべきではないらしい。今回は個人的な自動入力コードということで... - こちらのサイトを参考にした(React で作られた input タグに対して、外部から onChange を発火させたい)。React での情報があまりなかったので大変ありがたい。
作成手順(React・セレクトボックス)
- テキストボックス
<input>
では_valueTracker
を使ったが、なぜかセレクトボックス<select>
だと使えない。 - そこで以下のようにコードを変更する
javascript: (function () {
const name = document.getElementById("name");
- name.value = "山田";
- name._valueTracker.setValue("");
+ const nativeSetter = Object.getOwnPropertyDescriptor(
+ window.HTMLSelectElement.prototype,
+ "value"
+ ).set;
+ nativeSetter.call(name, "山田");
name.dispatchEvent(new Event("change", { bubbles: true }));
})();
- こちらを参考にした([OutSystems]JavaScript で Input の値を変更する方法)。
Reactが本来のsetter関数を書き換えるのであれば、書き換えられる前のsetter関数を使って値を設定すればよい、というアイデア。
よくそんなこと思いつくなあ...
作成手順(React・ラジオボタン)
ラジオボタン<input type="radio">
では、ラジオボタン要素を取得してclick()
メソッドを実行するだけでなぜか値が反映される。これでいいかは分からないが、まあ個人的なコードということで...
stackoverflowにclick()
を使っている回答があったので真似したら動いた。
(function () {
document.getElementById("a").click();
})();
感想
何ヵ月か前にも自動入力に挑戦して、React でのやり方が分からず断念していた。一歩前進できてうれしい。
Discussion