JavaScriptの条件付きコンパイル

コードの一部にIEでだけ実行する処理を入れたいときにちょっと便利っぽい「条件付きコンパイル」について覚えたので自分用にメモ。
Webでしか使えないのでさらっといきます。

基本

JavaScript内で「/* 〜〜 */」と書くとその部分はコメントになり、中になにか書いても実行されない。
ただしIE4+上で実行した場合は「@cc_on」と書くことで条件コンパイルが有効になり、「/*@ 〜〜 @*/」の中身や「//@ 〜〜」の行がコメントアウトされなくなる(=処理が実行される)。

/*@cc_on @*/
/*@
  alert("Hello IE!");
@*/

IE以外の場合はそのままコメントアウトされるので、なにごとも起こりません。
ちなみに「/*@cc_on @*/」のとこは「//@cc_on」でも可。*1

/*@cc_on
  alert("Hello IE!");
@*/

とか

/*@cc_on alert("Hello IE!"); @*/

とかって書くのもおk。

応用(@if...@elif...@else...@endステートメント

条件コンパイルが有効のとき、特殊な条件分岐の書き方ができる。
たとえばこんなの*2

/*@cc_on
  if (@_jscript_version >= 5.7) {
    alert("IE7以上ですね!");
  }
  else if (@_jscript_version >= 5.6) {
    alert("IE6ですね! そろそろ乗り換えたら?");
  }
  else {
    alert("ちょ、IE5.5以下とか……");
  }
@*/

↓こんな風に書ける。

/*@cc_on
  @if (@_jscript_version >= 5.7)
    alert("IE7以上ですね!");
  @elif (@_jscript_version >= 5.6)
    alert("IE6ですね! そろそろ乗り換えたら?");
  @else
    alert("ちょ、IE5.5以下とか……");
  @end
@*/

何の意味があるかというと、コメント区切りを工夫すれば「ある特定の環境のIE」と「それ以外の環境のIE + 他ブラウザ」とで分岐ができるようになるわけです。

/*@cc_on
  @if (@_jscript_version <= 5.6)
    alert("IE6以下ですね! そろそろ乗り換えたら?");
  @else @*/
    alert("IE7以上か、その他のブラウザですね。"); //★
  /*@end
@*/

4行目の後ろに「@*/」が付いているのがポイント。IE以外のブラウザでもここで一度コメント部分が終了するので、★のついた行はそのまま実行されます。もちろん「@_jscript_version <= 5.6」がfalseになったIEでもそれは同じ。あとは条件分岐を終了する@endをIEのみが処理するように「/*@ 〜 @*/」で囲んでやればおk。

……実際使うことがあるかどうかよくわからんけど、もし見かけたらこれを思い出すことにしよう。

さて、長い前フリでしたが

要するにこれです。

javascript:(function(){var%20a=/*@cc_on!@*/false?document.selection.createRange().text:window.getSelection().toString();location.href='http://clip.livedoor.com/clip/add?link='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&tags='+''+'¬es='+((!!a)?encodeURIComponent('『'+a+'』'):'')+'&jump=ref';})();

livedoorクリップで元記事を引用するときに引用符をつけるブックマークレット

最初についてる「/*@cc_on!@*/」が条件付きコンパイル使った部分。
これはつまり論理否定演算子の「!」をコメントで囲んで、直後のfalseを「IEのときだけtrue」にしている。あとは単純に分岐してるだけ。
クロスブラウザにするなら、window.getSelection()が使えるかどうかで分岐なのかなあ」と思っていたのですが、こっちのが簡単ですね。最初見たとき*3リアルで顔が (@∀@)? ってなったのですが、調べてすっきりしましたとさ。

参考にしたのはこのあたりです。
http://www.javascriptkit.com/javatutors/conditionalcompile.shtml
http://msdn.microsoft.com/ja-jp/library/cc391875.aspx
http://www.tagindex.com/kakolog/q4bbs/1201/1523.html

ところでこいつを見てくれ。こいつをどう思う?

応用のところで書いた分岐は、ぐぐって見つかったいくつかのコードを参考にしているのだけど……

//@cc_on
/*@if (@_jscript_version <= 5.6)
    alert("IE6以下ですね! そろそろ乗り換えたら?");
  @else @*/
    alert("IE7以上か、その他のブラウザですね。");
  //@end

こうやって書けるんじゃあるまいか。と思った。そんだけ。

*1:もちろんこれ自体コメントアウトしておかないとエラーになる。

*2:ちなみに分岐条件に使ってる「@_jscript_version」は組み込み変数。IEのバージョンでもなくJavaScriptのバージョンでもなくJScriptのバージョンです。組み込み変数はこれ以外にもいろいろあるみたい。続きはMSDNで!

*3:正確に言えば見たことだけはあったけどさっぱり意味がわからなかった