No.03 Javascript の記述方法
09 複数ブラウザへの対応
 
 これまで紹介してきた簡易的なJavascriptは基本的にはどのブラウザでも動作するため問題ありませんが、複雑な処理をブラウザに行わせる為には、各社が独自に拡張したJavascript命令を用いなくてはならないため、同一Webページでこういった処理を行わないといけない場合は、条件分岐文を用いて、ブラウザを判別する必要が出てくることになります。

 ブラウザは自分自身を紹介するためにいくつもの信号を出しており、Javascriptでこれらの信号を検出すれば、ブラウザ個別の信号を取り出すことが可能になります。

エージェントの検出

  var VarUsrAgt = navigator.userAgent.toLowerCase();

  document.write("User-Agent = " + VarUsrAgt);

	

 [ navigator ] オブジェクトは、ブラウザの持つ様々な情報をJavascript側に送信します。 navigator.userAgent オブジェクトは、ブラウザの持っているエージェント信号を返してくるので、ブラウザの持つ Mozilla バージョンやアプリケーションバージョン、OSの種類などを検出できます。

IE5.0 / Win2000
mozilla/4.0 (compatible; msie 5.5; windows nt 5.0)
NS6.0 / Win2000
mozilla/5.0 (windows; u; windows nt 5.0; ja-jp; m18) gecko/20001108 netscape6/6.0
NS4.7 / Win2000
mozilla/4.75 [ja] (windows nt 5.0; u)



検出プログラムの例

  var VarUsrAgt = navigator.userAgent.toLowerCase();
  isNS2 = navigator.appVersion.charAt(0) == 2 && 
                          navigator.appName.charAt(0) == "N";
  isNS4 = (document.layers) ? 1 : 0;
  isNS40= navigator.appVersion.substr(0,3) == "4.0" && 
                          navigator.appName.charAt(0) == "N";
  isNS6 = navigator.appVersion.charAt(0) == 5 && 
                          navigator.appName.charAt(0) == "N";
  isIE2 = VarUsrAgt.indexOf("msie 2.") != -1;
  isIE3 = VarUsrAgt.indexOf("msie 3.") != -1;
  isIE4 = (document.all) ? 1 : 0;
  isIE5 = VarUsrAgt.indexOf("msie 5.") != -1;
  isIE55= VarUsrAgt.indexOf("msie 5.5") != -1;
  isIE6 = VarUsrAgt.indexOf("msie 6.") != -1;

  isMac = (navigator.appVersion.indexOf("Mac") != -1) ? 1 : 0;
  isWin = (navigator.appVersion.indexOf("Win") != -1) ? 1 : 0;
  isX11 = (navigator.appVersion.indexOf("X11") != -1) ? 1 : 0;

  isMenu = ((isNS4 && !isX11) || 
    (isIE4 && !isMac && !isX11) || (isNS6) || (isIE5)) ? 1 : 0;

  isNotJava = ((isNS2) || (isIE3) || (isIE2) ) ? 1 : 0;
  if (!isNotJava){
    isMZ1 = navigator.productSub == 20010323;   //MOZILLA 0.8.1
  } else {
    isMZ1 = false
  }
	

 全ての命令文を解説していくとページの関係上膨大になってしまうので、ここでは私が普段使用しているバージョン情報取得アルゴリズムを掲載しました。 こちらを参照してもらいながら、説明します。

 [ navigator.appName ] は、ブラウザの名前を返してきます。 一般的に使用頻度の高いIEとNSでは、下記のような信号を返します。
navigator.appName
IE
Microsoft Internet Explorer
NS
Netscape

 上記の判別プログラムで [ navigator.appName.charAt(0) ] としているのは、 この識別信号の最初の一文字を取り出してチェックするという意味合いを持っています。[ charAt([x]) ] は、指定した文字列の左から[x + 1]番目の文字1文字を抽出します。(例:右から2文字目の場合は x = 1 となる) ということは、 [ navigator.appName.charAt(0) ] を指定すると、IEの場合は「M」NSの場合は「N」を返すということになります。

 [ navigator.appVersion.charAt(0) ] は、ブラウザから帰ってくるバージョン情報を返してきます。 ただ、このバージョン情報はブラウザの持っているスクリプトや内部システムのバージョン情報で、必ずしもブラウザの表層的なバージョンと一致するとは限らないので、注意が必要になります。
navigator.appVersion
IE3.0
2
NS3.0
3
IE4.0
4
NS4.0
4
IE5.0
4
NS6.0
5
 例えば、[ navigator.appVersion ]だけを判別式とした場合、IE4、IE5、NS4の区別は付きませんし、[ navigator.appName ]を複合条件式に入れても、IE4とIE5の区別をつけることが出来ないので注意が必要です。
Netscape Navigator の判別式
isNS2
navigator.appVersion.charAt(0) == 2 && navigator.appName.charAt(0) == "N";
isNS6
navigator.appVersion.charAt(0) == 5 && navigator.appName.charAt(0) == "N";

 ネットスケープはマイクロソフト社とサンマイクロシステムズ社との間で翻弄しつづけ、非常に今苦しい立場に居るブラウザです。 このため、IEに比べると、個々のバージョンによって動作するアルゴリズムの違いが多いため、安全対策として Netscape 4 に関しては別の判別式を導入しています。
Netscape Navigator 4 の判別式
isNS4
(document.layers) ? 1 : 0;
 [ document.layers ]は、NS4で採用されたレイヤー表記上の命令ですが、NS6では廃止されています。 このため、マイナーバージョンを返すアルゴリズムを造るためには、命令そのものが対応しているかどうかをチェックするのが一番確実であるといえます。
[ (document.layers) ? 1 : 0; は、document.layer が undefined の場合は false 、文字列を返した場合は true を返す判別式です。 具体的には、 NS4の場合、文字列が [ object LayerArray] と返されます。

Internet Explorer の判別式
isIE2
VarUsrAgt.indexOf("msie 2.") != -1;
isIE3
VarUsrAgt.indexOf("msie 3.") != -1;
isIE4
(document.all) ? 1 : 0;
isIE5
VarUsrAgt.indexOf("msie 5.") != -1;
isIE55
VarUsrAgt.indexOf("msie 5.5") != -1;
isIE6
VarUsrAgt.indexOf("msie 6.") != -1;

 IEの判別は前記したとおり、内部バージョン情報があいまいであるため、最初に説明した [ navigator.userAgent.toLowerCase() ] オブジェクトを用いて、ブラウザのエージェントを取り出して検査する方式を取っています。
 [ indexOf("文字列") ] は、指定した文字列、上記表で言うところの [ VarUseAgt ] の中の文字との比較を行って、同一の文字が帰ってきた場合、その先頭文字列の位置を返し、存在しなかった場合は「-1」を返すオブジェクトです。
 この判別式の場合、文字列がどの位置にあるかどうかは関係なく、存在するかどうかが重要になってくるので、判別式が「 -1 」であるか否かをチェックする判別式としています。 この場合、 isIEx は、該当ブラウザであるとき「true」 それ以外のときは「 false 」と返してきます。
 尚、isIE4 が、isNS4 と同じように命令文の対応判別になっているのは、IE4以上が対応している場合 と、IE5から対応しているものとを判別するためです。 [ document.layer ]は、IE4でもIE5でも対応しているため、この判別式だと、isIE4 は、IE5以降でも true を返すことになります。

Mozilla の判別式
isMZ1
navigator.productSub == 登録日;
 Mozilla は、破棄された Netscape5 のスクリプトを改良して、フリー公開を進めている団体が開発しているブラウザで、非常に対応機種の多いのが特徴となっています。
 ただ、基本的に現時点(2001-06-01)ではまだ製品版として完成しておらず、幾つかのバグが報告されています。
 Mozillaブラウザは、駆動系がNetscapeベースである関係上、殆ど全ての識別信号は Netscape6 と同一のものが帰ってきます。 このため、Netscape6 と Mozilla(0.8.1) との判別には、別の方法で取得する必要があります。
 [ navigator.productSub ] は、ゲッコーに登録された日時を返すオブジェクトで、Netscape6 と Mozilla にのみ実装されているものです。 この登録日時は、当然Netscape6 と Mozilla では異なるので違う信号が帰ってきます。「20010323」は、2001年3月23日に、ゲッコーに登録されたということを意味しており、この日時をチェックして Mozilla か否かを判別しています。
Mozilla の判別式の一覧 (Windows)
Mozilla 0.6.0
navigator.productSub == 20001205;
Mozilla 0.7.0
navigator.productSub == 20010109;
Mozilla 0.8.0
navigator.productSub == 20010215;
Mozilla 0.8.1
navigator.productSub == 20010323;
Mozilla 0.9.0
navigator.productSub == 20010505;
Mozilla 0.9.1
navigator.productSub == 20010607;
 基本的にこちらが確認した限りでは、 Mozilla シリーズは、Netscape6 の命令で動作する ようです。 上記の「isNS6」判定式でも、Mozilla は「 true 」で帰ってきますし、判定式を組み込む必要はそれほど高くは無いでしょう。 ただ、正式公開前の Mizilla は結構バグが報告されており、こういった対処のためにスクリプトを動作させないといった回避ルーチンを作成する際には、重要になってくると思います。


Operating System の判別式
isMac
(navigator.appVersion.indexOf("Mac") != -1) ? 1 : 0;
isWin
(navigator.appVersion.indexOf("Win") != -1) ? 1 : 0;
isX11
(navigator.appVersion.indexOf("X11") != -1) ? 1 : 0;
 ブラウザ判別式では、開いているブラウザがどのタイプかをチェックします。
 基本的に各OSとも様々なバージョンがありますが、 例えば Windows98 と Windows2000 のIE5には、動作上の実質的な違いはありませんので、判別式として加える必要は無いと考え、大まかなブラウザ判別のみを行うようにしています。
補足:isX11 は、X-Window搭載OS、Linux等が判定対象になります。

スクリプト動作対象の判別式
isMenu
((isNS4 && !isX11) || (isIE4 && !isMac && !isX11) || (isNS6) || (isIE5) ) ? 1 : 0;
 さて、最終的なスクリプトの判別式では、具体的に動作するブラウザかそうでないかを判定する条件式にになります。
  「1」NS4でOSがX11でない場合
  「2」IE4でOSがMacで無い場合
  「3」NS6の場合
  「4」IE5の場合
 の3つをチェックして、どれかが該当した場合に true となります。
 これは、同一バージョンの同一ブラウザであっても、OSによってはバグがあったり動作しなかったりといった報告が寄せられてきているため、その対応策です。

Javascript非対応系の判別式
isNotJava
((isNS2) || (isIE3) || (isIE2) ) ? 1 : 0;
 この判別式は、最低限度動作するJavascript命令ですらエラーを返してくる初期のブラウザを、スクリプトの動作範囲外に追いやるためのもので、IE2とIE3、NS2がこれに該当します。
 具体的には、画像のホップアップといった命令は、これらのブラウザでは対応しておらず、エラーを返してきます。このため、プログラムの動作を円滑に行うには、このプログラムでくくってしまうことが望ましいと考えています。



ページの最上段へ移動します