📌

React を使った テキストボックスやセレクトボックスに Bookmarklet で自動入力させる

2023/11/12に公開

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では表面上値を変更できても、内部の値は変更できないようだ。

コードを少し変える

diff
(function () {
  const name = document.getElementById("name");
  name.value = "山田";
+  name._valueTracker.setValue("");
+  name.dispatchEvent(new Event("input", { bubbles: true }));
})();

作成手順(React・セレクトボックス)

  • テキストボックス<input>では_valueTrackerを使ったが、なぜかセレクトボックス<select>だと使えない。
  • そこで以下のようにコードを変更する
diff
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 }));
})();

Reactが本来のsetter関数を書き換えるのであれば、書き換えられる前のsetter関数を使って値を設定すればよい、というアイデア。

よくそんなこと思いつくなあ...

作成手順(React・ラジオボタン)

ラジオボタン<input type="radio">では、ラジオボタン要素を取得してclick()メソッドを実行するだけでなぜか値が反映される。これでいいかは分からないが、まあ個人的なコードということで...

stackoverflowclick()を使っている回答があったので真似したら動いた。

(function () {
  document.getElementById("a").click();
})();

感想

何ヵ月か前にも自動入力に挑戦して、React でのやり方が分からず断念していた。一歩前進できてうれしい。

Discussion