/*@ @*/はIEの振り分け?

Webテンプレート HTML+CSSサンプルコード集



0   名前: jax_6 : 2007/12/30(日) 19:23  ID:5WwKRY4N sub-7c
http://www.tagindex.com/cgi-lib/q2bbs/patio.cgi?mode=view2&f=1598&no=9

http://www.tagindex.com/cgi-lib/q2bbs/patio.cgi?mode=view2&f=1523&no=10
の「@」の意味がよくわかりません。
記号なので検索もやりにくいです。
これはいったい何なのでしょうか。

二つめのリンクでは
http://www.tagindex.com/cgi-lib/q2bbs/patio.cgi?mode=view2&f=1523&no=11
というameさんの発言があり、「/*@ @*/はIEの振り分け」らしいですが・・

既に過去ログ等あったらすいません。

1   名前: 元帥 : 2007/12/30(日) 19:23  [URL]  ID:3e1fvlhs sub-bK
IE専用と予想できれば、Microsoftのサイトを見れば早いかな、と。
> 1. 一覧表ページがあると仮定
> 2. そのページにはこのような文字が含まれている筈だと仮定
> 3. その文字(思いついたオブジェクト名なり何なり)をANDで検索
http://www.tagindex.com/cgi-lib/q4bbs/patio.cgi?mode=view2&f=1383&no=1

Conditional Compilation Statements (JScript .NET)
http://msdn2.microsoft.com/en-us/library/7kx09ct1(VS.71).aspx

@if...@elif...@else...@end Statement (JScript .NET)
http://msdn2.microsoft.com/en-us/library/ct27x3xa(VS.71).aspx

JScript Deviations from ES3 の4.2辺り
http://wiki.ecmascript.org/lib/exe/fetch.php?id=resources%3Aresources&cache=cache&media=resources:jscriptdeviationsfromes3.pdf
※リンク先はPDFです。

> というameさんの発言があり、「/*@ @*/はIEの振り分け」らしいですが・・
発言の文脈を辿りますと、断定ではなさそうですが…。
/* コメント内に条件付きコンパイル */
/* @if 〜 */

2   名前: 元帥 : 2007/12/30(日) 19:23  [URL]  ID:3e1fvlhs sub-bK
>>1
すいません。
括弧で途切れてしまったようです。

Conditional Compilation Statements (JScript .NET)
http://msdn2.microsoft.com/en-us/library/7kx09ct1%28VS.71%29.aspx

@if...@elif...@else...@end Statement (JScript .NET)
http://msdn2.microsoft.com/en-us/library/ct27x3xa%28VS.71%29.aspx

3   名前: 匿名 ◆6lOezfNBvA : 2007/12/30(日) 19:23  ID:GOT.58AI sub-Cz
JScript の条件コンパイルが有効時(@cc_on)、//@...、/*@...@*/ 内が解析される。不要なら @cc_on を消せば、単なるコメントとして捨てられる。
//@cc_on

//@set @debug_mode = true;

function hoge (a) {
/*@
   if (@debug_mode) {
       output(a);
   }
  @*/
   return a;
}

>>1-2 にもあるが、@if...@elif...@else...@end で解析部を分岐できる。組み込み変数を使えば JScript のバージョンやプラットフォームも分かる。
//@cc_on

function hoge (a) {
/*@if (@_jscript_version < 5.0)
    alert('IE 4.0');
  @elif (@_jscript_version < 5.1)
    alert('IE 5.0');
  @elif (@_jscript_version < 5.5)
    alert('IE 5.01');
  @elif (@_jscript_version < 5.6)
    alert('IE 5.5');
  @else
    alert('IE 6.0 or higher');
  @end
  @*/
}

例えば、try...catch 文がサポートされたのは JScript 5.0 からで、IE4 では構文エラーが出る。エラーを出さないようにするには、条件コンパイルで IE4 には if 文を使えば良い。過去の実装にとって未知の構文でも同一ソースに書くことができるわけだ。



いわゆるブラウザ分岐に関して言えば、未だに下記のようなのが散見される。
if (document.getElementById) {
  ...;
} else if (document.all) {
  ...;
} else if (document.layers) {
  ...;
}

これには問題がある。第一に、getElementById は DOM Level 1 では HTML モジュールだが Level 2 では Core モジュールに変更された。つまり、上記の書き方では DOM Level 2 HTML をサポートしているか判定できない。第二に、document.all はもはや IE だけのものではないこと。document.all 判定に通っても、IE 用のオブジェクトを実装している保証はない。第三に、上にも書いたように、IE でもバージョンによってサポートするものが違うということ。

ゆえに、分岐するのであれば、これから使用するプロパティの有無を判定しなければならない。
function addEvent (node, type, listener, useCapture) {
  if ('undefined' != typeof node.addEventListener) {
    return node.addEventListener(type, listener, useCapture);
  }
  if ('undefined' != typeof node.attachEvent) {
    return node.attachEvent('on' + type, listener);
  }
  throw Error('NOT_SUPPORTED_ERR');
}

しかし、この関数を呼び出すたびにブラウザ分岐するのは無駄だ。下記のように最初に 1 度だけ関数を作成すれば、ほとんどのケースでは事足りる。
var contains = (function () {
  if ('undefined' != typeof document.addEventListener) {
     return function (node, type, listener, useCapture) {
        return node.addEventListener(type, listener, useCapture);
     };
  }
  if ('undefined' != typeof document.attachEvent) {
     return function (node, type, handler) {
       return n.attachEvent('on' + type, handler);
     };
  }
  return function () {
    throw Error('NOT_SUPPORTED_ERR');
  };
} )();

もっとも、関数式にしてしまうと実行順序が面倒になる。関数宣言のまま処理冒頭に一度だけブラウザ分岐させたい場合、条件コンパイルが便利だ。
//@cc_on

function addEvent (node, type, listener, useCapture) {
  try {
    return node.
            /*@if (5 <= @_jscript_version)
                attachEvent('on' + 
              @else@*/
                addEventListener(
            /*@end@*/
                  type, listener, useCapture);
  } catch (e) {
    throw Error('NOT_SUPPORTED_ERR');
  }
}

こうすれば、少なくとも IE 用の分岐はソースコンパイル時の一度だけで済む。実行中にいちいちブラウザ分岐させないようにすれば、ユーザスクリプトとしての再利用も容易になる(GreaseMonky とか user.js とか)。

まあ実際にはもう少しうまく書く必要があるのだが、数十行程度のコードではべた書きしてしまっています。また、これを参考にちょっとしたプリプロセッサを作れば、1 つのソースコードから様々なソースコードを自動生成できる。

4   名前: jax_6 : 2007/12/30(日) 19:23  ID:5WwKRY4N sub-7c
>>1-2
>IE専用と予想できれば、Microsoftのサイトを見れば早い
確かにそうでした。条件付きコンパイルですか!ありがとうございます。資料もたくさんありましたね・・。
http://flv86.net/js/js/index.htm
↑話がそれますがリンク先から辿れるここ、便利ですね。

>>3
なるほど!条件付きコンパイルを使うと、実行の度にブラウザの条件分岐をするのではなく、コンパイル時のみの分岐で済むのが利点ということですね。納得致しました。
>最初に 1 度だけ関数を作成
の書き方も勉強になります。詳細な解説ありがとうございました。
GreaseMonky(はてなダイアリー:http://d.hatena.ne.jp/keyword/Greasemonkey)とかの話には若干ついていけていません。
条件付きコンパイルにしろ最初に1度だけ関数を作成する方法にしろ、使いこなせるようになるのはだいぶ先になりそうです;



「/*@」についてもやもやしていた謎が解けました。ありがとうございました!

5   名前: 匿名  : 2007/12/30(日) 19:23  ID:3OgogSYs sub-6Z
やたらと使うものではない。

一覧へ戻る