発 展 知っておくと役立つかも (上級者向け)
 応 用 知っておくと便利 (中級者向け)
 基 本 知っておくべきです (初心者向け)

Q: Netscape4.*は IMGタグに onClickイベントが無いようなのですが。
 Aタグで画像をはさんで、Aタグに onClickを書きましょう。もちろん最新ブラウザでも動きます。
 <A href="#" onClick="hoge();return false;"><IMG src="et2002.gif" alt="ET"></A>
このとき、クリックされてもページ移動しないように、onClickに return false;を入れるのがポイントです。

Q: JavaScriptのバージョン指定をしたのに、古いブラウザでエラーになるのですが。
 イベントから関数を呼び出す形になっていると、エラーが出ます。
<SCRIPT language="JavaScript1.2">
<!--
function hoge(){
  alert("");
}
//-->
</SCRIPT>

<FORM>
<INPUT type="button" onClick="hoge()">
</FORM>
 上記の例だと、JavaScript1.2以前のブラウザでは、関数hoge()が定義されないのでエラーになります。以下のようにダミー関数を書きましょう。
<SCRIPT language="JavaScript">
<!--
function hoge(){}
//-->
</SCRIPT>

<SCRIPT language="JavaScript1.2">
<!--
function hoge(){
  alert("");
}
//-->
</SCRIPT>

<FORM>
<INPUT type="button" onClick="hoge()">
</FORM>
 JavaScriptでは、同じ関数が定義されると、後から定義されたものが有効になります。この例では、JavaScript1.2に対応していないブラウザではダミー関数が実行され、何も起きません。JavaScript1.2に対応しているブラウザでは、alertが出ます。

Q: JavaScriptにswitch文ってありませんでしたっけ?
 あります。ただしJavaScript1.2から追加されたので、一部に対応していないブラウザがあります。
 if〜else if文でも替わりが利くので、特別な必要がないかぎりこちらを使いましょう。

Q: 変数に格納できる文字数に制限はありますか?
 仕様上は特に定められていませんが、大きすぎる変数を確保するとブラウザが不安定になります。ハングアップしない範囲で調べてみました。

a = "ああああああ…";
alert(a.length);
で、正常にアラートを出せるか実験。(メモリ96MB)

変数に格納できる文字数 :
NN2 30万バイト超 (半角30万文字、全角15万文字)
NN3 30万バイト超 (半角30万文字、全角15万文字)
NN4 10万バイト超 (半角10万文字、全角5万文字)
IE5 100万バイト超 (半角100万文字、全角50万文字)

Netscapeは、ハードディスクをガリガリ言わせてスワップし始めます。
IEの限界は不明ですが、100万バイトでもまだまだ余裕です。

普通に使う分には、これだけ使えれば不自由しないでしょう。

Q: C言語のソースを流用して「漢字判定スクリプト」を作ったのですが、はじいてしまう漢字があります。
for (i=0; i < str.length; i++) {
  if ( !((str.charAt(i) >= "亜") && (str.charAt(i) <= ""))){
    alert("漢字で入力してください");
  }
}
文字列の大小比較をすると、大小関係が文字コードの順になります。
"CAMEL" < "CASTER" < "MARLBORO" < "マイルドセブン" < "葉巻"

 シフトJISコードの並びでは、漢字は「亜」〜「」です。上のコードは正しいように見えますが、NN4やIE4/5では、一,丁,七,万,丈,三,不,与などの漢字がチェックに引っかかってしまいます。
 この現象はブラウザがユニコード化されたために起こります。ユニコードでは、中国・日本・韓国の漢字が統合され新たに並べ直されたため、シフトJISとは全く別の配列になっています。漢字の範囲は「一」〜「龠」、「焉v〜「I」です。

NN4、IE4/5/6での正しいコードは、
for (i=0; i < str.length; i++) {
  if ( !((str.charAt(i) >= "一") && (str.charAt(i) <= "龠")) 
       && !((str.charAt(i) >= "") && (str.charAt(i) <= "I"))){
    alert("漢字で入力してください");
  }
}
ユニコードがらみの問題はまだまだ出てきそうですね。

Q: JavaScriptエラーの詳細を見るにはどうするのですか?
 ページを見に来る人にとっては、エラーを読んでも理解不能で、理解できたとしても修正する手段がありません。エラーを見るのに関心があるのは、Webページ開発者だけです。そのため、即座にエラーダイアログが出ないようになっています。

<IE4以上>
 IEでエラーを表示しない設定にした場合は、ステータスバーに (!)ページでエラーが発生しました と表示されます。詳細を見るには(!)をダブルクリックしてください。

<Mozilla 1.0>
 Tools -> Web Development -> JavaScript Consoleで開くことができます。

<Netscape6>
 タスク -> ツール -> JavaScriptコンソール で開くことができます。

<Netscape4>
 URLの欄に javascript: と入力しEnterキーを押します。

※エラーのあるスクリプトを実行すると、ステータスバーに、
JavaScript error: Type 'javascript:' into Location for details
[日本語訳] JavaScriptエラー: 詳細を見るには、URLの欄に 'javascript:' と入力してください
と出ます。それに従って javascript: と入力すると、JavaScriptコンソールが開きます。


 MozillaやNetscapeは、URL欄に javascript: と入力すればJavaScriptコンソールが開きます。毎回入力するのが面倒な人は、このJavaScript Errorを右クリックしてブックマークに追加しておきましょう。

 自動的にJavaScriptコンソールを出したいという場合は、Netscapeをインストールしたフォルダにある prefs.js を開いて、以下の一行を追加しておきます。
user_pref("javascript.console.open_on_error", true);


Q: ソースを見られたり、無断コピーされるのを防ぎたいのですが。
 マイクロソフトに、Script Encoderというツールが公開されています。それを使うとスクリプトを暗号化できますが、Windows Script 5.0がインストールされている環境 (IE5以上) でしか実行されず、IE4やNetscape,Mozilla,Opera,iCab等ではエンコードしたスクリプトが動作しません。知的財産の保護を取るか、互換性を取るか難しいところです。ダウンロードはこちら。(日本語版。x86互換プロセッサ用コマンドラインプログラム)
 なお、Script Encoderは特にスクリプトをコンパイルするわけではなく、文字を置き換えるだけです。暗号強度はお世辞にも強いとは言えません。

 どんなブラウザでも動くように自前の暗号化ルーチンを作っても良いのですが、復号化ルーチンをJavaScriptで書く必要があるため、知識のある人には分かられてしまいます。

 無断コピーを防ぐには、外部jsファイルを使うだけでも一定の効果があります。
 また、location.href.indexOf("…")等で URLに含まれる文字をチェックし、if文を使ってスクリプトを実行しないようにする方法を使うのも良いですね。

 最近、JavaScriptで右クリックを禁止しているサイトが増えていますが、ソースを隠す目的ならば無意味です。右クリック以外でもソースを見る方法はいくらでもあります。無闇にユーザビリティを下げるようなスクリプトを埋め込むのはやめましょう。

Q: 外部jsファイルを使うと文字化けするのですが。
 Mac版IE4.5やwin版IE5.01では、外部jsファイルを Unicode(UTF-8)にしないと文字化けします。開発者がjsファイルの文字コードを指定できないというのははっきり言ってバグです。
 ただ、UTF-8で書いても Unicodeに対応していないブラウザがありますから、どんなブラウザでも文字化けしないようにするには Unicodeのエスケープシーケンスと 従来のURLエンコードを併記します。

alert("あいうえお")の場合

var UTFesc = "\u3042"

if(UTFesc.length == 1) alert("\u3042\u3044\u3046\u3048\u304A")
else alert(unescape("%82%A0%82%A2%82%A4%82%A6%82%A8"))

変数 UTFescは、\uXXXX形式の文字列を Unicodeとして扱ってくれるか判断するために使います。
それ以外のブラウザは、従来のURLエンコードを unescapeして使います。

この文字列を得るには、文字コード表とにらめっこしてもいいのですが、IEとNNがあれば escape関数で調べられます。
IE : escape("あいうえお") -> %u3042%u3044%u3046%u3048%u304A (Unicode)
NN : escape("あいうえお") -> %82%A0%82%A2%82%A4%82%A6%82%A8 (URLエンコード)

 確実を期すなら、外部jsファイルは使わないのが一番です。(ページ内のスクリプトは、本文と同じ文字コードとして扱われます)

Q: JavaScriptに2000年問題はありますか。
 getYearメソッドを使っているところで問題が発生する可能性があります。getYearメソッドは西暦年を返しますが、1900年代は下2桁、2000年はブラウザによって100を返したり、2000を返したりとまちまちです。常に4桁で返すgetFullYearメソッドもありますが、対応していないブラウザもあります。

DateObject = new Date();
year = DateObject.getYear();
if(year < 2000) year += 1900;


のように、変数yearに4桁にした年号を格納して、変数yearを利用するという方法で対処しましょう。

※ IE4, NN4は、lastModifiedを Dateオブジェクトとして解釈すると、getYearで 0 が返る場合もあります。
 そのため、最終更新日表示で使う場合は、こちらを参考にしてください。

Q: Dateオブジェクトで、2月30日のような存在しない日付を指定しても動作保証できますか。
 これはブラウザ側が柔軟にできていますので、自動的に3月2日 (うるう年の場合は3月1日) として扱われます。同様に、13月は翌年1月として扱われます。マイナスの月を指定しても大丈夫です。
 ただし、-1日のような負の日数を指定したときはブラウザによって差異が出ます。NN2〜4やIE5だと計算してくれますが、NN4.5は負の数を1日として扱います。(IE3, IE4は未確認)
 しかし、DateObject.setDate(DateObject.getDate()-1) のようにsetDateを使う時は、マイナスが渡されても正確に計算してくれますので、あまり心配はいらないでしょう。

 また、年は設定できる範囲があります。範囲外の日付を設定するとブラウザによっては異常終了することもあるので気を付けましょう。
fromto
NN21970年1月1日2038年1月19日
IE31970年1月1日?(未確認)
NN3100年1月1日32767年12月31日
NN40年1月1日32767年12月31日
NN4.5-271821年4月21日
(1970年1月1日 - 100000000日)
275760年9月13日
(1970年1月1日 + 100000000日)
IE5
※ 紀元一世紀は西暦が2桁なので、setFullYear()でないと設定できません。(setYear()等では自動的に1900年代とされてしまう)
setFullYear()は ver4.0のブラウザから使えます。

Q: ページを、一定時間経過後に他のページに飛ばしたいのですが。
次に読み込むページが newpage.htmlで、5秒後に飛ぶ場合、

<SCRIPT language="JavaScript">
<!--
tid = setTimeout("location.href='newpage.html'", 5000)
//-->
</SCRIPT>

としますが、JavaScriptを使わなくてもできます。
HEADタグの中に、
<META http-equiv="refresh" content="5; URL=newpage.html">
と書きます。

Q: リンクをクリックした時に何かをさせたいのですが、動作後、リロードしたり別のページへ飛んでしまいます。
 リンクやクリッカブルマップは、元々クリックしたときに他のページへ飛ぶようにできていますから、これを無効にする書き方をしなければなりません。

<A href="" onClick="window.open('http://www.kantei.go.jp','','width=300,height=400');return false">
首相官邸
</A>


首相官邸

このように return falseを書かなかった場合、呼び出し元のページがリロードされたり、他のページに飛んでしまいます。

<A href="javascript:window.open(・・・)">
のように書くこともできます。

Q: 文字列をJavaScriptで書き出すときに、改行したいのですが。
 document.writeでHTML文書を出力するときは<BR>と書けばできます。
しかし、フォームやアラートに出力する場合には使えません。文字列の中に普通に改行を入れると、行が分割されるためエラーが出ます。改行を入れたい場合は、特殊文字 \n を使ってください。(Windowsの場合は \r\n と書くのが正式。けれど \n で大丈夫らしい)

 例: document.write("今日のメニュー<BR>ほうれん草のおひたし")
 例: alert("診断結果\n肉も食えよ")

その他の特殊文字は以下の表にまとめてあります。

特殊文字出力される文字
\bバックスペース
\f改ページ(フォームフィード)
\n改行(LF)
\r復帰(CR:キャリッジリターン)
\tタブ
\\通貨記号(またはバックスラッシュ)
\"
\'
文字としてのクォーテーションマーク
\uXXXXユニコード文字 (JavaScript1.3から。XXXXは16進数)

Q: 古いブラウザでは特定の文字が文字化けします。何とかなりませんか?
 特殊文字以外で \ を書き込むと、無視されて文字としては出力されません。
 このことが引き金となって、2バイト文字(全角)を使う環境では困ったことが起こります。例えば、「表示」という文字を出そうとすると「侮ヲ」になってしまいます(シフトJISの場合)。「表示」の文字コードは 955C 8EA6ですが、5Cには \ が割り当てられているため、これが無視された結果 958E A6と見なされてしまうのです。
 こうならないようにするには、「表\示」と書き込みます。内部では、特殊文字の \\が入力されたと判断し、\ 一個に置き換えられます。
 この他にもコード内に5Cを含む文字は化けますので、注意が必要です。

なお、ユニコード化されている最近のブラウザ(IE4以降、NN4.06以降)では大丈夫です。

Q: フレームの中身への直接アクセスを禁止したいのですが
if(parent.location == location) location = "(FRAMESETタグの置いてあるURL)";
このスクリプトをフレームコンテンツに書き込むと、直接読み込まれたときにFRAMESETタグの置いてあるURLにジャンプします。
フレームの中身としての読み込みだけ許可されます。


Q: フォームを表示専用にしたいのですが。
<TEXTAREA onFocus="this.blur()"></TEXTAREA>
<INPUT type="text" onFocus="this.blur()">
このようにすればフォーカスが移動しなくなるので、編集できないようになります。

IE4以降やNetscape6以降なら、HTMLのreadonly属性を使った方がいいでしょう。
<INPUT type="text" readonly>


Q: データの型変換をしたいのですが。
 JavaScriptでは、型を自動変換してくれるので、普段は数値型とか文字列型を意識しなくていいのですが、時には型変換が必要な場合もあります。

1)文字列を数値に変換する

"3" - 0 == 3
eval("3") == 3

a = "5" (文字列型)
b = "3" (文字列型)

a + b -> "53"
(a - 0) + (b - 0) -> 8
eval(a) + eval(b) -> 8
2)数値を文字列に変換する

"" + 3 == "3"


c = 2 (数値型)
d = 4 (数値型)

c + d -> 6
"" + c + d -> "24"


Q: document.writeを繰り返すと遅いのですが、高速化できませんか。
 Netscape4は、document.writeの結果を一旦別の所に出力するため、繰り返すと遅くなります。
 変数に文字を足していく形にして、最後にdocument.writeで変数を出力すると早くなります。

 ---このページで公開している「自動更新カレンダー その2」で実験---
document.writeの繰り返し : 1745msec
文字列変数を利用 : 599msec

 MPU : MMX Pentium 166MHz
 RAM : 96MB (EDO-DRAM)
 ブラウザ : NN4.5
 実に65%の高速化です(^_^) ※なお、IE5でも35%高速化しました。
 これを踏まえて、「自動更新カレンダー その3」では、変数を利用し document.writeを一回にまとめました。


Q: Javaでどんなことができますか?
 JavaのことはJavaのページで聞きましょう。
 JavaScriptをJavaと略すくらいなら、スクリプトと略した方がまだましです。