【このページ内のトピック: 「Ctrl-矢印」でフォーカス移動・「G/T」連打で自動ナビ】
「NS,NN=Netscape Navigator」「IE=Internet Explorer」の略です。
IE3では外部ファイルに記述されたJavaScriptを読み込めません。
【外部スクリプトの読み込み】
<script language="javascript" src="keynavi_ja.js"></script>
その為、HTML内に記述するJavaScript内で
外部ファイル中に宣言されている変数や関数を参照しているとIE3では
「'...'は宣言されていません。」という参照エラーになります。
これを避けるには 外部ファイル内で宣言されている変数の有無をみて
ファイルが読み込まれたかを確認します。
例えば「keynavi_ja.js」内では「KL_LOADED=1;」が定義されていて
以下のように利用されます。
【ファイルが読み込めたか確認する】
<script language="javascript" src="keynavi_ja.js"></script>
<script language="javascript"><!--
if(self['KL_LOADED']){
...<keynavi_ja.js内の変数・関数を参照可能>...
}
//-->
</script>
各フレームのHTML内で外部ファイルのスクリプトを読み込む時には注意が必要です。
Netscape4.xでは「if(document.layers)」や「if(document.forms)...」
などの確認をしただけで外部スクリプトの実行が中断されます。
フレームを使っていないページでも 閲覧者が該当ページを
フレーム内で表示させる場合があります。
(フレームを使った別ページからリンクされた場合など。)
その場合でも同様の現象が発生してしまいます。
つまり自分が作ったページでフレームを使ってなくても
この現象が発生し得るので注意します。
実験ページ(NS4で試してみて下さい)
回避策1:起動スクリプトを作り本文内で呼ぶ
document以下のオブジェクト
(layers,forms,anchors,links,images,cookie,title,width,heightなど (locationは除く))
を参照する場合、
外部スクリプトには 変数や関数の「定義」だけを書いておき
HTMLの<body>内の<script> 或いは<body onLoad=....>
で上記文を含むようなスクリプトを実行するようにします。
単なるブラウザ判別だけなら document.layersの代わりに
navigator.appNameやnavigator.appVersionを
使ってもいいでしょう。
それらのオブジェクトについては実行は中断されないようです。
【セットアップ関数をHTML内で実行】
<script language="javascript" src="path/MyScript.js"></script>
<script language="javascript"><!--
MySetup();
...
//-->
</script>
回避策2:フレームを強制解除してしまう
上記の問題を避けるには
フレーム内でページを表示された場合に NS4時のみに
下記のようにしてフレームを強制的に解除するのも1つの方法です。
【Netscapeの場合はフレームを強制解除】
<script language="javascript"><!--
if(navigator.appName=="Netscape" && navigator.appVersion.indexOf("4.")==0 &&
parent!=self)
top.location=self.location.href;
</script>
これによりNS4ユーザの好みに関わらず
フレーム内で該当ページを表示することができなくなります。
しかしながら「戻るボタン」を押しても前のページに戻れないなど
ユーザビリティに問題があります。
回避策3:KeyNavi拡張用関数 kl_setup_ex()を定義する
KeyNaviを使っている場合は この方法がラクです。
「kl_setup_ex()」はKeyNaviの起動スクリプト「kl_setup()」実行時に
自動で呼ばれるカスタマイズ用関数です。
当該名の関数が存在すれば 自動で呼び出されます。
この関数は通常はスクリプトソースが読まれたときに実行、
「Netscape4.x&フレーム利用」の場合は
全てのdocumentが読み終わった後(=onLoad時)に実行されます。
そのためスクリプトの実行が中断されることはなく Netscapeのバグを回避できます。
カラクリ:
まずブラウザ判別をしNS4かどうか判定しています。
次にフレームを使ってるかどうか「parent!=self」を確認します。
いずれも真の場合は全ての処理を「onload」時に行うよう
「window.onload=(関数);」などとしてハンドラ関数を登録しています。
【kl_setup_ex()の利用サンプル】
<script language="javascript"><!--
function kl_setup_ex(){
if(document.layers){
document.alyers["id1"].visibility="show";
document.alyers["id1"].bgColor="blue";
}
(または。。。)
kl_layer_show("id1");
kl_layer_setbgcolor("id1","blue");
}
</script>
おまけ:普遍的な値参照はTopフレームを利用
(2003/4/10追加)
単に属性値の確認だけを行いたいときは
フレームのdocumentではなく親Windowのdocumentにアクセスすると良いでしょう。
例えばNS4でクッキーの値を参照したい場合は
「document.cookie」ではなく「top.document.cookie」
とします。
NS3.01では実際に実行されなくても
「syntax error.」となるので関数の定義はif文の外で行います。
同様に「変数=function f(){...}」といった記述も存在するだけでエラーです。
この場合は代わりに「new Function("実行文")」とするとエラーになりません。
JavaScriptでは暗黙の型変換が積極的に行われるようです。
IE6では下記は全て真(true)です。
新しいブラウザでは代わりに 何かの言語と同じく「===」が使えるみたいですが
IE3,NS4.05などではソース内にその記述が存在するだけでエラーになります。
(IE3.0:「構文エラー。」 NS4.05:「syntax error」)
(新しいブラウザ(IE4.0やNS4.5以上)では上記を実行しても何も起きませんがIE3.0,NS4.05ではエラーになります。)
しょうがないので値の比較時には下記の関数を使っています。
【比較関数 kl_eq(a,b)】
function kl_eq(a,b){
return (typeof(a)==typeof(b) && a==b);
}
属性の有無を確認するために
「if(親オブジェクト.属性)」或いは「if(親オブジェクト["属性名"])」
としますが IE3で「document.write」関連の属性確認をすると
「OLEオートメーションでサポートされていないプロパティまたはメソッドです。」
などとエラーになります。
いろいろ試してみたところ以下のものでエラーです。
これらはIE3やNS3でもサポートされているらしいので
チェックしないほうがいいでしょう。
(2002/4/3追加)
NS4やIE4では実際に実行されなくても
スクリプト内に「try{...}catch(e){...}」という記述があるだけで
エラーになります。
(NS4:「try is a reserved identifier.」 IE4:「構文エラーです。」)
(新しいブラウザでは上記を実行しても何も起きませんがNS4,IE4ではエラーになります。)
その為この構文はスクリプトタグの指定を工夫するか
eval()を使い IE5+、NS6+のみで実行するようにした方がいいでしょう。
(上記はIE4,NS4で実行してもエラーにはなりません。)
Netscape4.04/4.05では 日本語の2バイトコードの扱いが他のブラウザと
異なります。
例えば「"ひらがな".length」が8になります。
また「"ひらがな".charCodeAt(N)」は負数が返ります。
なお、Netscape4.08,4.5,4.8などではこの問題はありません。
日本語の文字列処理ではこれらを利用して分岐処理するといいでしょう。