クライアント側スクリプトというのは、HTML文書に対して外部から協調して作業をしたり、あるいはHTML文書中に埋め込まれていたりするプログラムのことです。このプログラムは、当該文書が読み込まれた時点、あるいはリンクがアクティブにされたときなど何か他のタイミングで起動します。HTMLのスクリプト機能は、スクリプト言語の種別は問いません。
スクリプトを使うと、動きのあるHTML文書や、読み手に反応する文書を作成できます。例えば次のように。
HTML文書に添付できるスクリプトには、次の2つの型があります。
注。 スクリプト関連では、附記B.7に、スクリプトマクロに関する注記があります。
この節では、スクリプトに対応しているユーザエージェントに関係する内容を記します。
<!ELEMENT %Script; -- script statements -->
<!ATTLIST SCRIPT
charset %Charset; #IMPLIED -- char encoding of linked resource --
%ContentType; #REQUIRED -- content type of script language --
%URI; #IMPLIED -- URI for an external script --
defer (defer) #IMPLIED -- UA may defer execution of script --
>
開始タグ: 必要、終了タグ: 必要。
属性の定義
他に使用可能な属性
HEAD要素中、あるいはBODY要素中に、何回でも記すことができます。
スクリプトそのものは、SCRIPT要素の内容として記すこともできますし、外部ファイルとして参照することもできます。src属性の設定がない場合、ユーザエージェントは「SCRIPT」要素の内容を、ここで扱うべきスクリプトであると解釈する必要があります。src属性の値がURIだった場合、ユーザエージェントは「SCRIPT」要素の内容を無視して指定先URIのファイルを参照する必要があります。charset属性で指定されている符号化方法は、src属性が指定する参照先ファイルの符号化方法を指定したものであって当該SCRIPT要素の符号化方法とは無関係であることに注意して下さい。
スクリプトは、ユーザエージェントに登録されている実行環境<script engines>によって検定・実行されます。
個々のスクリプトデータの記し方は、使用するスクリプト言語の文法に従うことになります。
HTMLには専属のスクリプト言語がありませんから、スクリプトを書く場合にはどのスクリプト言語を使用するかをユーザエージェントに明示する必要があります。明示する方法は、使用する基本スクリプト言語を一回宣言する方法と、文書中で逐一宣言する方法の2通りがあります。
ある文書中にスクリプトを利用する場合、使用するスクリプト言語をHEAD要素中でMETA宣言によってまとめて宣言しておくべきです。
<META http-equiv="Content-Script-Type" content="type">
上記の "type" の部分にスクリプト言語名をMIMEタイプで記します。例えば、 "text/tcl"、 "text/javascript"、 "text/vbscript" のように。
META宣言がなされていない場合、当該文書の基本使用スクリプト言語は、HTTPヘッダの「Content-Script-Type」によっても判定できます。
Content-Script-Type: type
上記の "type" の部分にMIMEタイプでスクリプト言語名が記されます。
ユーザエージェントは、基本使用スクリプト言語が何であるかを、次の優先順位で判断する必要があります。
ベースとなるスクリプト言語を指定していないHTML文書で内在イベントが記されているものがあれば、それは文法的に正しくない文書です。ユーザエージェントはそのような文書のスクリプトも解釈しようと試みるでしょうが、仕様準拠基準として解釈が要請されているわけではありません。また、オーサリングツールはこのような文書を吐き出さないようにし、常に基本スクリプト言語の設定を行う必要があります。
当該文書中に現れる全てのSCRIPT要素で、type属性を通じた使用言語の設定が必要なわけですが、基本スクリプト言語が宣言されていた場合、各SCRIPT要素での設定は基本使用言語を上書きします。
下の例では、基本スクリプト言語が「text/tcl」に設定されており、ヘッド部にあるSCRIPT要素は「text/vbscript」による外部スクリプトを参照するようになっています。ボディー部のスクリプトは「text/javascript」で書かれています。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <HTML> <HEAD> <TITLE>A document with SCRIPT</TITLE> <META http-equiv="Content-Script-Type" content="text/tcl"> <SCRIPT type="text/vbscript" src="/someplace.com/progs/vbcalc"> </SCRIPT> </HEAD> <BODY> <SCRIPT type="text/javascript"> ...JavaScriptのプログラム... </SCRIPT> </BODY> </HTML>
各スクリプト言語は、スクリプト中からHTML要素を参照するための手法を持っています。ただしこの仕様書ではその標準手法を定義したりはしません。
けれども、要素の参照は、その要素の固有名を目印にして行われるようにすべきだということは記しておきます。スクリプト実行環境<scripting engines>は、各要素の特定を行う場合、次の手順を踏んで下さい。目的となる要素にまずname属性とid属性の両方が設定されている場合はname属性の方を優先すること。片方しか設定されていない要素の場合は設定されている方を使うこと。
注。 スクリプト機能を利用したい方へ。内在イベント絡みの規格は頻繁に変更され得ます(例えばスクリプトとイベントの結合方法など)。内在イベント絡みの話題はW3C Document Object Model Working Groupによって随時フォローされます。(詳しくはW3Cのサイト http://www.w3.org/ をご覧下さい。)
属性の定義
読み手がユーザエージェントを通して反応してくれることに対して、複数のイベントを連結させて1つの動作が起こるような文書を作成することも可能です。上に掲げた全内在イベントの値はスクリプトであり、それらのスクリプトは、イベントが発生する毎に動作を始めます。スクリプトの記述方法は各スクリプト言語の文法に依存します。
フォームのコントロールを表すINPUT、 SELECT、BUTTON、 TEXTAREA、LABEL要素は、各々固有の内在イベントを発生させます。これらの要素をフォーム以外の部分で使用し、当該HTML文書のグラフィカルなユーザインタフェースとして機能させるような使い道もあり得ます。
例えば、フォームを送信する目的でなく、何か違う目的でサーバにデータを送ってもらうために文書中に押しボタンを設けたいという場合もあるでしょう。
ここで、内在イベントに基づいたユーザインターフェイス機能を実現可能なコントロール要素をいくつか例示します。
次の例では、テキスト入力窓「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」あるいは同等機能の命令文が現在の文書を書き換えるのではなく新しい文書を作り出すということに、注意して下さい。
文書の読み込みと同時に動作するスクリプトは、文書の内容を動的に変更することが可能です。その能力はスクリプト言語自体に依存します。(例えば命令文「document.write」は、複数のベンダーがサポートしています。)
文書の動的変更については、次のようにモデル化できるでしょう。
こうしたSCRIPT要素の処理の前後どちらにおいても、当該HTML文書はHTMLのDTDに適合している必要があります。
次の例は文書の動的変更がどのようになされるかを示すものです。
<TITLE>Test Document</TITLE> <SCRIPT type="text/javascript"> document.write("<p><b>Hello World!<\/b>") </SCRIPT>
上記のスクリプトは、次のようなHTMLマークアップと同じ効果を発揮します。
<TITLE>Test Document</TITLE> <P><B>Hello World!</B>
この節では、スクリプトをサポートしないユーザエージェントでも理解可能な文書の設計方法について記します。
<!ELEMENT %block;)+
-- alternate content container for non script-based rendering -->
<!ATTLIST NOSCRIPT
%attrs; -- %coreattrs, %i18n, %events --
>
開始タグ: 必要、終了タグ: 必要。
このNOSCRIPT要素は、スクリプトが実行されない環境での代替物となる文章を記すために利用します。NOSCRIPT要素の内容は、スクリプトに対応するユーザエージェントにおいては、次の場合にのみ表示されることとなります。
クライアント側スクリプトをサポートしていないユーザエージェントは、「NOSCRIPT」要素の内容を表示する必要があります。
次の例文のような文書を読み込むと、SCRIPT要素の内容を実行できるユーザエージェントの場合は文書を動的に生成し、実行できないユーザエージェントの場合はリンクを表示し、リンクを辿ってデータを読んでもらうことになります。
<SCRIPT type="text/tcl"> ...本文中にデータを追加するようなTclスクリプト... </SCRIPT> <NOSCRIPT> <P>Access the <A href="http://someplace.com/data">data.</A> </NOSCRIPT>
SCRIPT要素に対応していないユーザエージェントの場合、その内容であるスクリプトデータそのものを普通の文章と一緒に表示してしまいがちです。JavaScript、VBScript、Tclを初めとするスクリプト実行環境は、スクリプトそのものをSGMLのコメントとして記せるような仕組みを備えています。そこで、コメントとして記しておけば、SCRIPT要素に対応していないユーザエージェントの場合はスクリプト内容を無視し、コメント式記法に対応しているスクリプト実行環境においてはスクリプト内容が実行されることとなります。
スクリプト内容を非対応ユーザエージェントから隠すための別の方法は、全スクリプトを外部データとして提供し、src属性による参照によって実行させる形をとることです。
JavaScriptでのコメント式記法
JavaScriptでは、「SCRIPT」要素の開始タグ直後の行頭に「<!--」が記してあれば、その行に書かれている内容を無視するお約束となっています。JavaScriptの言語体系でのコメントは、行頭に「//」を記した1論理行で表します。[スクリプト全体を非対応ユーザエージェントから隠すためにSGMLコメントとして記す場合] 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のコメントとなります。前記の伝で、SGMLコメントを閉じる部分は単引用符から始まる文として記します。
<SCRIPT type="text/vbscript"> <!-- Sub foo() ... End Sub ' --> </SCRIPT>
TCLでのコメント式記法
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>
注。 ユーザエージェントによっては 、[HTMLの] コメントが、[<-- に続くテキストデータの中で] 最初の「>」が現れた時点で閉じられていると解釈するものがあります。そこで、そのような [間抜けな] ユーザエージェントからスクリプトデータを隠すためには、命令の表記などを書き換えたり(例えば「x > y」と書く代わりに「y < x」と書くとか)、各スクリプト言語の流儀で「>」を置き換える方法を採るなどの必要があります。