ブックマークレット

作成日:2013-09-23
最終更新日:

ブックマークレットとは

ブックマークレットとは、 ウェブブラウザのブックマークで起動し、ブラウザの情報を参照したり更新したりするプログラムをいう。 通常は JavaScript で実装される。

hello, world の表示

別ウィンドウでの表示

チェックボックストグル

チェックボックス1 チェックボックス2 チェックボックス3 チェックボックス4

オプションの選択

オプションとは、複数の選択肢から一つを選ぶダイアログの形式である。 通常のインターフェースではラジオボタンを用いる。下記のスクリプトでは、 名称が selection_1 となっている複数の入力から値が radiobutton_3 となるものをチェックする。 下記の表示は、名称 selection_j の値 radiobutton_k をとるものが、 オプション j-k を表している。 現在の状態が何であっても、ブックマークレットを起動するとオプション1‐3がチェックされることを確認されたい。

オプション1―1 オプション1―2 オプション1―3

オプション2―1 オプション2―2 オプション2―3

DOM 構造

これをブックマークレットに入れておけば、DOM 構造が見える。

select 要素

select 要素は複数の選択肢から一つを選ぶダイアログの形式である。 これについてはオプションと同じであるが、 インターフェースが「ポップアップメニュー」「ドロップダウンメニュー」「リストメニュー」 などの形をとる。ラジオボタンと異なるのは、選ぶ前では選択肢が一部しか見えていないということだ。 昔習ったインターフェースの知識では、選択肢がすべて見えるようにラジオボタンを使うのが原則である、 ということだった。

さて、selecte 要素のブックマークレットの例である。上から順番に i (i = 1 ... 4) 番目の分野で、 i 番目の項目が選ばれるしかけになっている。

好きな果物:
好きな音楽家:
好きな点心:
好きな言語:

内と外

自分のページをインターネット上で見ていて、誤りを見つけたとする。そのとき、エディターを起動して訂正するが、 その後イントラネット(というより localhost )で誤りが訂正されたことを確認したい。 そのときのためのブックマークレットである。

ボタンの自動クリック

ログイン画面などで、IDとパスワードを入力してログインボタンをクリックすると先に進むことがある。 これをブックマークレットで実現することができる。

上記は変数 document やメソッド getElementById が繰り返されていて、スペリングのあやまりによるバグを起こしやすい。 そこで同じ変数やメソッドを統一して扱えるように短縮したのが次の記述である。この方法は、リンク集5に拠った。

注意:下記はサンプルのため送信できない。上記ブックマークレットを実行したり、下記[送信]ボタンをクリックしたりしたときの動作は、 単にこのページの上部に戻るだけである。

ID : PASSWORD :

ボタンクリックのイベントで submit 関数が起動されない場合は、button 要素の可能性がある。 そのときは次のようにする。ただし、ボタンに id 属性として "botton2" が定義されているとする。また、短縮形のみ掲げる。

注意:下記はサンプルのため送信できない。上記ブックマークレットを実行したり、下記[送信]ボタンをクリックしたりしたときの動作は、 単にアラートウィンドウを表示するだけである。

ID : PASSWORD :

ちなみに、input 要素には、ボタン(type='button')のほかに多くつかわれるものとして、テキスト(type='text')、パスワード(type='password')、 チェックボックス(type='checkbox')、ラジオボタン(type='radio') などがある。

ボタンの連続クリック

ボタンで画面ページを前後にめくるようなページでは使えるだろうか。 ASAHINet 掲示板 で試してみようと思う。

ここで、「HREFリンククリックによる別URLへの遷移」と「ボタンクリックによる同じURLにおけるPOSTメソッドの実行」に分けてみよう。 前者を A とし、後者を B とする。以下、A と B の操作について、適宜正規表現を使って表す。 まず、A 単独では次のようになる。

次に、B 単独では次のようになる。

ここまでくれば、AB という操作と BB という操作がどうなるか、考えてみよう。まず、同じ操作を行う BB から考える。 単純に次のように書くだけでうまくいかないだろうか。

試してみると BB ではなく、B だけである。なぜだろうか。全く同じ文を二度実行させているのもおかしいので、 文を関数として連続して実行するように書き直してみた。

しかし結果は BB ではなく、B だけである。おそらく、タイミングの問題なのだろうと考え、 タイミングを制御する関数を加えた。

しかし結果は変わらず、一度しかページは変わらない。setTimeout ではなく、次のようにsetInterval にしてみたが結果は変わらない。

javascript:(function () { function timer(){setTimeout(location.reload,10000); } timer();})()

面を繰る

前の問題は解けなかったが、その後も考えてみた。 もう少し簡単な問題を考えよう。次のような画面があるとする。



そして [次へ] のボタンをクリックすると次の画面が出るとする。


以上が次々とつながっているものとする。さて、 subsec001からsubsec010が出ている最初のページが徐々にページをめくっていき、 所望のsubsec[0-9][0-9][0-9]にたどり着く方法はあるだろうか。 仮に下記がフレームの下部にあるとする。上部はただのタイトルのページとする。 フレームのスクリプトは次のとおりとする。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" 
	  http://www.w3.org/TR/html4/frameset.dtd">
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta http-equiv="Content-script-type" content="text/javascript" />
  <title>Javascript Frame Control</title>
</head>
<frameset rows="*1,*5">
  <frame name="up"   src="title.html">
  <frame name="down" src="page0.html">
</frameset>
</html>

タイトルのページは次のようになるだろう。

<html>
<head>
  <title>Title</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta http-equiv="Content-script-type" content="text/javascript" />

  <script type="text/javascript">
    var id;
    var keyword = "subsec021";   // 探している文字列 
    function doNext() {
      var links = window.top.frames[1].document.links;

      for (var i = 0; i < links.length; i++) {
//      alert(links[i].text); // IE の場合は text のかわりに innerText かもしれない
        if (links[i].text == keyword) {
          window.clearTimeout(id);
          alert(keyword + "が見つかりました");
          return;
        }
      }
      var inputs = window.top.frames[1].document.getElementsByTagName('input');
      if (inputs.length < 1) {
        alert("何も見つかりませんでした");
        return ;
      }
      if (inputs[1].value != "次へ") {
        alert("何も見つかりませんでした。");
        window.clearTimeout(id);
        return;
      }
      inputs[1].click(); // [次へ] のクリック
      id = window.setTimeout("doNext()", 1000); // 1 秒後に次の画面を出す
    }
  </script>
</head>
<body>
<h1>Title</h1>
<p>
  <a href="javascript: doNext()">開始</a>
  <a href="javascript: window.clearTimeout(id)">停止</a>
</p>
</body>
</html>

リンク集

  1. ブックマークレット(jp.wikipedia.org)
  2. JavaScript::Bookmarklet(bookmarklet.daa.jp)
  3. chrome チェックボックス 全選択 全てチェック(peroon.hatenablog.com)
  4. select 要素を選択する小ネタ(d.hatena.ne.jp)
  5. 任意のサイトで自動ログインするブックマークレットを作る(d.hatena.ne.jp)

まりんきょ学問所JavaScript 手習い > ブックマークレット


MARUYAMA Satosi