イントロダクション
ブラウザのブックマークに JavaScript を登録して実行する”ブックマークレット”というものがあります。ブックマークレットを利用すると、ブラウザ上で簡単な処理を実行でき、利用する場面によっては非常に便利です。
今回は、新しいウィンドウへ HTML を出力するブックマークレットを作成した時にハマった罠について記載します。
コード
ブックマークレットが実行されたら、新しいウィンドウへ HTML を出力するようにするため、以下のコードを作成しました。// 新しいウィンドウにデータを出力 var win = window.open(); win.document.write("<html><head><title>test</title></head><body></body></html>"); win.document.body.innerHTML = "<p>テスト!</p>";
このコードをブックマークレットとして実行するため、一行に圧縮し、javascript:を付けたものが以下のようになります。
javascript:var win=window.open();win.document.write("<html><head><title>test</title></head><body></body></html>");win.document.body.innerHTML="<p>テスト!</p>";
これを Chrome ブラウザのブックマークに登録し、ブックマークレットとして動作させてみました。
すると、確かに新しいウィンドウが開き、そこに HTML が出力されるのですが、ブックマークレットを実行するとき開いていたウィンドウにも同じく HTML が出力されていました。
他のブラウザでも同じブックマークレットを使用して実験した結果、次のようになりました。
Chrome
バージョン:
35.0.1916.114 m
動作:
確かに新しいウィンドウが開き、そこに HTML が出力される。
しかし、ブックマークレットを実行するとき開いていたウィンドウにも同じく HTML が出力される。
Internet Explorer
バージョン:
9.0.8112.16421
動作:
確かに新しいウィンドウが開き、そこに HTML が出力される。
ブックマークレットを実行するとき開いていたウィンドウは変化なし。
Firefox
バージョン:
29.0.1
動作:
確かに新しいウィンドウが開き、そこに HTML が出力される。
しかし、ブックマークレットを実行するとき開いていたウィンドウにも同じく HTML が出力される。
以上のように、ChromeとFirefox の場合には、ブックマークレットを実行するとき開いていたウィンドウにも同じく HTML が出力されるという現象が発生しました。
Internet Explorer では、ブックマークレットを実行するとき開いていたウィンドウは変化がありませんでした。
なぜこのような動作を示すのでしょうか?
一つ仮説をたてました。
ブラウザのアドレスバーへ
javascript:"テスト";
と入力して実行すると、そのときに表示していたページに
テスト
という文字列だけが表示されます。
つまり、プログラムの最後の行の戻り値がブラウザに表示されているのではないでしょうか。
最初に示したプログラムでいえば、
win.document.body.innerHTML = "<p>テスト!</p>";
が最終行であり、win.document.body.innerHTML がブラウザに表示されているとしたらつじつまが合います。
そこで、各ブラウザに置いて、
javascript:"テスト";
をブックマークレットとして登録して、実行してみました。
結果は予想通り、Chrome と Firefox では、そのときに表示していたページに
テスト
という文字列のみが表示されました。
また、Internet Explorer では、そのときに表示していたページに何の変化も起こりませんでした。
元のウィンドウの内容を変えないためにはどうすればよいか?
元のウィンドウの内容を変えずにブックマークレットを実行するには、ブックマークレットとして実行したい JavaScript を匿名関数として実行すればよいわけです。
匿名関数として実行するには、JavaScript コードを (function () { と })(); で囲みます。
例えば、
(function () { // 新しいウィンドウにデータを出力 var win = window.open(); win.document.write("<html><head><title>test</title></head><body></body></html>"); win.document.body.innerHTML = "<p>テスト!</p>"; )();
とし、これを一行に圧縮すると、
javascript:(function () {var win=window.open();win.document.write("<html><head><title>test</title></head><body></body></html>");win.document.body.innerHTML="<p>テスト!</p>"})();
となります。
このように、匿名関数として実行すれば、戻り値が返らないため、元のウィンドウの内容が変わることはありません。
コメントを投稿 (ここをクリックしてコメント投稿フォームを表示)
コメント投稿機能について