目次
クライアント側スクリプトとは、HTML文書と連携するか、または文書に直接組込まれるようなプログラムのことである。このプログラムは、文書がクライアント環境に読み込まれる際に実行されたり、リンクがアクティブになった際などに実行されたりする。HTMLがスクリプトをサポートする方法は、スクリプト言語の種別からは独立である。
スクリプトを用いると、著者は、HTML文書を高度に動的にしたり対話的にしたりする方向で拡張できる。例を挙げよう。
著者がHTML文書に添付できるスクリプトには、2つの種類がある。
注意。 本仕様には、スクリプトに関連して、 スクリプトマクロについての詳細情報がある。
以下の各節では、スクリプトをサポートするユーザエージェントに関係する内容を説明する。
<!ELEMENT SCRIPT - - %Script; -- script statements --> <!ATTLIST SCRIPT charset %Charset; #IMPLIED -- char encoding of linked resource -- type %ContentType; #REQUIRED -- content type of script language -- src %URI; #IMPLIED -- URI for an external script -- defer (defer) #IMPLIED -- UA may defer execution of script -- >
開始タグ: 必須、終了タグ: 必須
属性定義
SCRIPT要素は、HTML文書にスクリプトを組み込むもので、 HEAD要素あるいは BODY要素に、何回出現してもよい。
スクリプトは、この SCRIPT要素の内容か、または外部ファイルで定義される。 src属性の設定がない場合、ユーザエージェントは当該要素の内容をスクリプトであると解釈しなければならない。 src属性の値がURIだった場合、ユーザエージェントは当該要素内容を無視し、このURIからスクリプトを取得する必要がある。 charset属性で指定されている文字符号化方法はsrc属性が示すスクリプトの符号化方法を示していて、当該 SCRIPT要素とは無関係であることに、注意されたい。
スクリプトはスクリプトエンジンによって評価される。スクリプトエンジンはユーザエージェントにとって既知でなければならない。
スクリプトデータのシンタクスは各スクリプト言語に依存する。
HTMLは特定スクリプト言語に依存しないため、著者はユーザエージェントに対し、各スクリプトの言語を明示しなければならない。スクリプト言語は、デフォルト宣言と局所宣言の双方で明示することができる。
著者は、文書中のすべてのスクリプトのデフォルトであるスクリプト言語を、 HEAD要素の META宣言で、次のように指定しなければならない。
<META http-equiv="Content-Script-Type" content="type">
このtypeは、スクリプト言語を示すMIMEタイプで、例えば、「text/tcl」、「text/javascript」、「text/vbscript」である。
META宣言が存在しない場合、デフォルトは「Content-Script-Type」HTTPヘッダで指定できる。
Content-Script-Type: type
このtypeも、スクリプト言語を示すMIMEタイプである。
ユーザエージェントは、次の優先順位に従ってデフォルトのスクリプト言語を決定する必要がある。
デフォルトのスクリプト言語を指定していない文書で 組込みイベントスクリプトが指定された要素を含むものは、不正である。ユーザエージェントはこれを解釈しようと試みてもよいが、解釈を試みるよう要求されるわけではない。 オーサリングツールは、著者が不正な文書を作らないですむよう、デフォルトスクリプト言語の情報を生成する必要がある。
文書中のどの SCRIPT要素インスタンスも、type属性が指定されていなければならない。あるSCRIPT要素のtype属性値は、当該要素のデフォルトスクリプト言語を上書きする。
次の例は、デフォルトのスクリプト言語を「text/tcl」と宣言している。ヘッダにはSCRIPT要素が1つあり、これは外部ファイルの、text/vbscriptであるスクリプトを用いる。本文にあるSCRIPT要素の内容は、text/javascriptで記されている。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <HTML> <HEAD> <TITLE>スクリプトがある文書</TITLE> <META http-equiv="Content-Script-Type" content="text/tcl"> <SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc"> </SCRIPT> </HEAD> <BODY> <SCRIPT type="text/javascript"> …JavaScriptのスクリプト… </SCRIPT> </BODY> </HTML>
各スクリプト言語には、スクリプト内からHTML文書オブジェクトを参照するための規約が存在する。本仕様は、HTML文書オブジェクトを参照するための標準機構を定義するものではない。
しかしながら、スクリプトから要素への参照は、要素名に従わねばならない。スクリプトエンジンは、要素を識別する際に次の優先基準に従う必要がある。まず、name属性と id属性の双方が設定されている場合はname属性が優先する。次に、どちらか一方の場合は、ある方を用いる。
注意。 HTML文書の著者への助言。組込みイベントの領域では、例えばスクリプトとイベントとの結合方法など、頻繁に変更があり得る。この領域の研究は、W3Cの文書オブジェクトモデル作業班のメンバーが行なっている。より詳しい情報はW3CのWebサイト http://www.w3.org/ で得られる。
属性定義
ユーザがユーザエージェントと対話する際に発生する複数のイベントと1つの動作を結びつけることも可能である。上に列挙した「組込みイベント」はどれも、スクリプトを値に取る。このスクリプトは、当該要素に関係するイベントが発生する度に常に実行される。 スクリプトデータのシンタクスは、各スクリプト言語に依存する。
フォームのコントロール要素である、INPUT, SELECT、BUTTON、 TEXTAREA、並びにLABEL要素は、すべて何らかの組込みイベントに反応する。これらの要素がフォームの外部に出現する場合、これは文書のグラフィカルなユーザインターフェースを増強するために使われていると思われる。
例えば、アクティブになった際に、フォームを提出するのではないがサーバと交信をするような押しボタンを文書に組込みたいと考える著者もあろう。
ここで、組み込みイベントに基づくユーザインターフェース機能と利用可能なコントロールの例を幾つか示す。
次の例では、userNameへのテキスト入力が要求される。ユーザが入力フィールドを離れようとする際、 onblurイベントがJavaScriptの関数を呼び出し、userNameに適切な値が入力されているかどうかが検定される。
<INPUT NAME="userName" onblur="validUserName(this.value)">
更に別のJavaScriptの例を示す。
<INPUT NAME="num" onchange="if (!checkNum(this.value, 1, 10)) {this.focus();this.select();} else {thanks()}" VALUE="0">
今度はテキストフィールドのイベントハンドラであるVBScriptの例を示す。
<INPUT name="edit1" size="50"> <SCRIPT type="text/vbscript"> Sub edit1_changed() If edit1.value = "abc" Then button1.enabled = True Else button1.enabled = False End If End Sub </SCRIPT>
これをTclにした例を示す。
<INPUT name="edit1" size="50"> <SCRIPT type="text/tcl"> proc edit1_changed {} { if {[edit value] == abc} { button1 enable 1 } else { button1 enable 0 } } edit1 onChange edit1_changed </SCRIPT>
続いて、スクリプトの記述内容にイベントを組込んだJavaScriptの例を示す。まず、単純なクリックハンドラの例。
<BUTTON type="button" name="mybutton" value="10"> <SCRIPT type="text/javascript"> function my_onclick() { . . . } document.form.mybutton.onclick = my_onclick </SCRIPT> </BUTTON>
次に、もう少し面白いウインドウハンドラの例。
<SCRIPT type="text/javascript"> function my_onload() { . . . } var win = window.open("some/other/URI") if (win) win.onload = my_onload </SCRIPT>
これはTclでは次のようになる。
<SCRIPT type="text/tcl"> proc my_onload {} { . . . } set win [window open "some/other/URI"] if {$win != ""} { $win onload my_onload } </SCRIPT>
ここで、組込みイベントハンドラ中の「document.write」あるいはこれと等価な命令文が、現在の文書を更新するのではなく新しい文書を作成するのである点に注意されたい。
文書の読み込みと同時に実行されるスクリプトは、文書の内容を動的に変更できる。この変更能力は、スクリプト言語自体に依存する。例えば、複数のベンダーがHTMLオブジェクトモデルの「document.write」命令文をサポートしている。
文書の動的変更は、次のようにモデル化できる。
HTML文書は、どのSCRIPT要素の処理前も処理後も、HTML DTDに適合するよう制約される。
次の例は、スクリプトが文書をどのように動的に変更するかを示す。
<TITLE>テスト文書</TITLE> <SCRIPT type="text/javascript"> document.write("<p><b>Hello World!<\/b>") </SCRIPT>
上のスクリプトは、次のHTMLマーク付けと同等の効果を持っている。
<TITLE>テスト文書</TITLE> <P><B>Hello World!</B>
この節では、著者が、スクリプトをサポートしないユーザエージェントで機能する文書をどのように作ればいいかを説明する。
<!ELEMENT NOSCRIPT - - (%block;)+ -- alternate content container for non script-based rendering --> <!ATTLIST NOSCRIPT %attrs; -- %coreattrs, %i18n, %events -- >
開始タグ: 必須、終了タグ: 必須
NOSCRIPT要素を使うと、著者は、スクリプトが実行されない際の代替内容を提供できる。 スクリプトを認識するユーザエージェントは、 NOSCRIPT要素の内容を、次の場合にしかレンダリングしてはいけない。
クライアント側スクリプトをサポートしていないユーザエージェントは、この要素の内容をレンダリングしなければならない。
次の例では、SCRIPTを実行するユーザエージェントは動的に生成したデータをいくつか文書に組込み、スクリプトをサポートしないユーザエージェントでも、ユーザはリンクを通じてデータを取得できる。
<SCRIPT type="text/tcl"> …データを組込むためのTclスクリプト… </SCRIPT> <NOSCRIPT> <P><A href="http://someplace.com/data">data.</A>にアクセスされたし。 </NOSCRIPT>
SCRIPT要素を認識しないユーザエージェントは、要素の内容をテキストとしてレンダリングしようとしがちである。 JavaScript、VBScript、並びにTclを含むいくつかのスクリプトエンジンは、スクリプトの命令文をSGMLコメントに囲い込むことを許容している。 そこで、SCRIPT要素を認識しないユーザエージェントはコメントを無視するが、マトモなスクリプトエンジンはコメント中のスクリプトを実行する必要があることを理解する。
問題を解決する別の方法は、スクリプトを外部文書とし、 src属性で参照することである。
JavaScriptでのコメント化スクリプト
JavaScriptエンジンは、SCRIPT要素の始めに文字列「<!--」が存在することを許容し、この場合当該行の末尾までの文字を無視する。
JavaScriptは、「//」を当該行の末尾まで続くコメントの開始であると解釈する。この「//」は、【SGMLコメントを閉じる】文字列「-->」をJavaScriptパーサから隠すために必要とされる。
<SCRIPT type="text/javascript"> <!-- to hide script contents from old browsers function square(i) { document.write("The call passed ", i ," to the function.","<BR>") return i * i } document.write("The function returned ",square(5),".") // end hiding contents from old browsers --> </SCRIPT>
VBScriptでのコメント化スクリプト
VBScriptでは、単引用符によって、当該行の残りの部分がコメントとして扱われることとなる。そこで、単引用符が、VBScriptで「-->」を隠すために使われる。
<SCRIPT type="text/vbscript"> <!-- Sub foo() ... End Sub ' --> </SCRIPT>
Tclでのコメント化スクリプト
Tclでは、「#」が当該行の残りの部分をコメントとする。
<SCRIPT type="text/tcl"> <!-- to hide script contents from old browsers proc square {i} { document write "The call passed $i to the function.<BR>" return [expr $i * $i] } document write "The function returned [square 5]." # end hiding contents from old browsers --> </SCRIPT>
注意。 ブラウザの中には、最初の「>」という文字でコメントを閉じるものもある。こうしたブラウザからスクリプト内容を隠すためには、例えば「x > y」ではなく「y < x」と記すなど、関係演算子や移動演算子において被演算子を移項するといった手法や、各スクリプト言語固有の方法で「>」をエスケープするといった手法が取り得る。