* [CODE(HTMLe)[script]] 要素型 (HTML, XHTML 1) [1] [ABBR[[[HTML]]][Hypertext Markup Language]] の [DFN[[CODE(HTMLe)[script]] 要素]]は、 文書中に[[スクリプト]]を配置します。 [29] 仕様書: - [[HTML 4]] -- [CITE[18 Scripts in HTML documents]] -- [CITE[Element content]] - [[ECMA-290]] [9] :[[開始タグ]]:必須 :[[終了タグ]]:必須 :出現できる文脈:[CODE(HTMLe)[[[head]]]] の子として、または [CODE(HTMLe)[[[body]]]] 子孫の大抵の場所で :[[内容模型]]:[CODE(SGML)[[[CDATA]]]] ([[HTML 4]]), [CODE(XML)[[[PCDATA]]]] ([[XHTML 1]]) :[[属性]]: ,属性名 ,属性値 ,既定値 ,説明 ,出典 ,[CODE(HTMLa)[[[archive]]]],,,[NC4] ,[CODE(HTMLa)[[[charset]]]] ,[CODE(SGML)[%[[Charset]]]] , ,charset ヒント ,[HTML 4] ,[CODE(HTMLa)[[[classname]]]],[[逆ドメイン名]],,級名,[ECMA-290] ,[CODE(HTMLa)[[[defer]]]] ,([[真偽値属性]]) ,(偽) ,遅延評価 ,[HTML 4] ,[CODE(HTMLa)[[[event]]]] , , ,[[事象]] ,[HTML 4] 予約 ,[CODE(HTMLa)[[[for]]]] ,[CODE(SGML)[[[IDREF]]]] , ,対象 ,[HTML 4] 予約 ,[CODE(HTMLa)[[[id]]]],[CODE(SGML)[[[ID]]]],(なし),固有識別子 ,[CODE(HTMLa)[[[language]]]] , , ,スクリプト言語 ,[HTML 4] 非推奨 ,[CODE(HTMLa)[[[name]]]],,,,非標準 ,[CODE(HTMLa)[[[purpose]]]],,,実行目的,[ECMA-290] ,[CODE(HTMLa)[[[src]]]] ,[CODE(SGML)[%[[URI]]]] ,(内容) ,外部スクリプト ,[HTML 4] ,[CODE(HTMLa)[[[type]]]] ,[CODE(SGML)[%[[ContentType]]]] ,(必須) ,[[スクリプト言語]] ,[HTML 4] ,[CODE(XMLa)[[VAR[ev:]][[event]]]],[CODE(ABNF)[[[QName]]]],(なし),[[事象名]] ,[CODE(XMLa)[[VAR[ev:]][[observer]]]],[CODE(XML)[[[IDREF]]]],,[[事象観察器]] ,[CODE(XMLa)[[VAR[ev:]][[phase]]]],,, ,[CODE(XMLa)[[VAR[ev:]][[propagate]]]],,,[[伝播]]制御 ,[CODE(XMLa)[[VAR[ev:]][[target]]]],[CODE(XML)[IDREF]],,事象対象 [[#comment]] ** 出現できる文脈 [14] [CODE(HTMLe)[script]] 要素は、 [CODE(HTMLe)[[[head]]]] 要素や [CODE(HTMLe)[[[body]]]] 要素の中の大抵の場所に出現できます [SRC[HTML 4 18.2.1]]。 [15] しかし、[[不思議マーク付け]]の世界や多くの [[WWWブラウザ]]の実装では、 [CODE(HTMLe)[[[html]]]] タグの前後や [CODE(HTMLe)[head]] 要素と [CODE(HTMLe)[body]] 要素の間を含めて、あらゆる場所に出現できるようです。 [CITE[ダイナミックHTML入門]] (Bruce Campbell + Rick Darnell 著, 安藤慶一訳) という入門書では、 [Q[スクリプトの場所に関しては標準規格は必要ないようです]] などと電波を飛ばしているそうです。 [SRC[[CITE[いくつかの書籍のあらさがし]] ]] [[#comment]] ** 内容 [4] [CODE(HTMLa)[[[src]]]] 属性が指定されている場合、 スクリプトはその外部資源で定義されます。 [ABBR[[[UA]]][利用者エージェント]] は[[内容]]を無視し、指定された [ABBR[URI][統一資源識別子]] のスクリプトを取り寄せなければなりません。 [CODE(HTMLa)[src]] 属性が指定されていない場合、 [VAR[UA][利用者エージェント]] は内容をスクリプトとして解釈しなければなりません。 [SRC[HTML 4 18.2.1]] [30] [ABBR[[[XHTML]]][拡張可能ハイパーテキスト・マーク付け言語]] より前の [ABBR[HTML][ハイパーテキスト・マーク付け言語]] では、 [CODE(HTMLe)[script]] 要素の内容は [CODE(HTMLe)[[[style]]]] 要素の内容同様[[文字データ]] ([CODE(SGML)[[[CDATA]]]]) 宣言内容とされていました。 つまり、 [CODE(HTMLe)[script]] 要素内ではほとんどの[[マーク]]は認知されず、 [ABBR[[CODE(SGML)[[[etago]]]]][終了タグ開き]] ([CODE(HTML)[]]) が来たらそこで [CODE(HTMLe)[script]] 要素が終わることになっていました。 ですから、スクリプト言語の[[演算子]]などとして [ABBR[HTML][ハイパーテキスト・マーク付け言語]] の[[マーク文字]]が登場することがよくありますが、 そのような場合にもほとんど[[文字参照]]化する必要がありませんでした。 [36] [ABBR[[CODE(SGML)[[[ETAGO]]]]][終了タグ閉じ]] がかけないのは [CODE(JS)[[CODE(DOMa)[[[document]]]].[CODE(DOMm)[[[write]]]]]] のデータを作る時などにしばしば問題となり、その最盛期には、 これが原因でうまく動かないことに悩む人もよく見受けられました。 回避するためには、そのスクリプト言語の文字列連結を使ったり ([SAMP(JS)['<' + '/a>']])、 escape (quote) 機能を使ったり ([SAMP(JS)['<\/a>']])、文字生成関数を使ったり ([SAMP(VB)["<" & [[Chr]] (47) & "a>"]]) する方法がよく紹介されました。 [33] しかし、 [ABBR[[[XML]]][拡張可能マーク付け言語]] では [ABBR[[CODE(SGML)[CDATA]]][文字データ]] 宣言内容は使えないので、 [ABBR[[[XHTML 1]]][拡張可能ハイパーテキスト・マーク付け言語 1]] では [ABBR[[CODE(XML)[[[PCDATA]]]]][解析可能文字データ]] と宣言されています。 ですから、 [ABBR[[CODE(SGML)[STAGO]]][開始タグ開き]] ([CODE(XML)[<]]) は必ず [[escape]] して [CODE(XML)[<]] としなければならないなどの制限があります。 これを回避するために [[[CODE(XML)[CDATA]]区間]]を使う方法がよく紹介されますが、 そうすると多くの既存の [ABBR[WWW][World Wide Web]] ブラウザとの互換性が失われてしまいます。 ですから、 [ABBR[XHTML][拡張可能ハイパーテキスト・マーク付け言語]] で [CODE(HTMLe)[script]] 要素を使う時は [CODE(HTMLa)[src]] 属性を使った外部スクリプトとするのが良いと言われています。 [41] [CODE(HTMLa)[src]] で指定された資源が取得できない時に内容を使うとする説があります。 [CITE[SCRIPT - Client-side Script(jp)]] しかし、 [ABBR[HTML][ハイパーテキスト・マーク付け言語]] 4 の規定と矛盾します。 [WEAK[(この文書はほんとうに [ABBR[HTML][ハイパーテキスト・マーク付け言語]] 4 に基づいているのでしょうか?)]] [[#comment]] *** 擬似注釈宣言の使用 [18] [CODE(HTMLe)[script]] 要素に対応していない古い WWW ブラウザは、 [CODE(HTMLe)[script]] 要素内の[[文字データ]]も構わず解釈してしまいます。 そこで、 [CODE(HTMLe)[script]] 要素の内容としてスクリプトを記述するときには、 HTML の[[注釈宣言]]のように最初に [CODE(HTML)[]] をつけることが慣習となっています。 HTML 4 によれば、これは HTML の機能ではなく、[[スクリプト機関]]の機能とされています。 この機能に対応している言語には [[JavaScript]], [[VBScript]], [[Tcl]] があるようです。 [SRC[HTML 4 18.3.2]] より正確には、この3つの言語は [CODE(HTMLe)[script]] 要素の内容の一番最初の非[[空白]]文字列が [CODE[]] は、3つの言語のいずれも、それだけで書くことはできず、 それぞれの言語の注釈の内容として (JavaScript の場合は [SAMP(JS)[// -->]] のようにして) 書くことが必要らしいです。 [Q[らしい]]というのは、正確にこれを規定した仕様がないからです。 HTML 4 は[Q[スクリプト機関]]によるものだと言っていますから、 スクリプト言語の言語仕様かなにかに規定があってもよさそうなものですが、 そのようなものは見たことがありません。また、 HTML に直接埋め込まれていない [[ECMAScript]] のスクリプトのソース・コードに [CODE[ ]PRE] のように自然言語の注釈を入れておくことがよく行われていました (初期の使用例にそう載っていたからみんなで真似したのでしょう)。 (この例のように開き (のようなもの) の後に書くこともできましたが、 閉じの前に書くのが普通だったと記憶しております。) 後にこのような冗長なことはせず、 [PRE(HTML)[ ]PRE] のように簡単に書くようになりました。 [35] また、[Q[裏技]]的なものとして、 [PRE(HTML)[ ]PRE] のような書き方が紹介されることもありました。 (この例のようになぜかスクリプトの途中に書いているものもあれば、 注釈宣言 (のようなもの) の前後に書いているものもありました。 どこに入れるにせよ、書く内容は一行にするか、 うまくして行頭にスクリプト言語の注釈導入子が来るように調整することが重要です。 また、 [CODE(SGML)[[[etago]]]] が使えないことにも注意が必要です。) [38] スクリプト言語の演算子として [CODE[>]] を使うことが良くありますが、 古いブラウザの中には注釈宣言を [CODE[>]] で終えてしまうものがあることが知られています。 [SAMP(JS)[[VAR[x]] > [VAR[y]]]] のような式は [SAMP(JS)[[VAR[y]] < [VAR[x]]]] と書くことで回避できます。 [SRC[HTML 4 18.3.2 Note]] もっとも、そのようなブラウザは HTML 4 の時点でも骨董品ですし、 HTML 4 も特にそうするべきだなどとは言っていません。 参考文献: - [16] [CITE[ 内の要素はすべてコメントで囲んだ方が安全です。]] [[#comment]] ** UA による利用 [28] [CODE(HTMLe)[script]] 要素によるスクリプトは、 文書の読込み時に実行されます [SRC[HTML 4 18.1]]。 [CODE(HTMLa)[src]] 属性による外部スクリプトは優先的に実行されるという説を唱える人がいますが、 根拠は不明です。特定の UA ではそうなのかもしれませんが、 少なくても HTML 4 は何も規定していません。 但し、 [CODE(HTMLa)[[[defer]]]] 属性や [CODE(HTMLa)[[[event]]]] 属性は実行時機に影響するのかもしれません。 [[#comment]] ** 歴史 [2] [CODE(HTMLe)[script]] 要素は、 [[NN2]] が [[LiveScript]] と共に実装したのがはじめであると考えられています。 [20] [CODE(HTMLe)[script]] 要素がはじめて公式な仕様書に入ったのは 1997年1月の [[HTML 3.2]] でした。しかし、 このときの最終的な勧告では詳細が決まらず、 将来の版のために予約すると述べるに留まっていました。 > [SRC[HTML 3.2 DTD]] [12] その後1997年12月の [[HTML 4]] で、 [CODE(HTMLe)[script]] 要素型はようやく正式な仕様の一部となりました。 当時 [[WinIE]] や [[NN]] が実装していた [CODE(HTMLe)[script]] の基本的な機能が仕様に入りましたが、 WinIE だけが実装していた [CODE(HTMLa)[event]] 属性と [CODE(HTMLa)[for]] 属性は、 将来のために予約とされました。 [24] 1998年に勧告された [[DOM 1]] やその後の [[DOM 2]] では、 [CODE(HTMLe)[script]] 要素型に対応する [CODE(DOMi)[[[HTMLScriptElement]]]] 界面が定義されています。ここでは、標準の属性の他、 [CODE(HTMLa)[for]] 属性と [CODE(HTMLa)[event]] 属性も[Q[将来の使用のために予約]] として定義だけされています。 [25] >>24 そんな将来くるのかな〜。来たら嫌だな〜 [26] >>24-25 将来の使用は M$ の仕様の間違いじゃないのかな。 [32] >>24-26 その後 [[XHTML 1]] が標準化されましたが、予約2属性はやはり正式な仕様には昇格せず、 このまま忘れ去られようとしています。しかし、両属性の機能は拡張して汎用化されて [[XML事象]]仕様の一部として標準化されました (2002年)。 [[#comment]] ** 実装 [31] [CODE(file)[[[CGI.pm]]]] は、 XHTML 出力 mode だと、 [[注釈宣言]]内に [[[CODE(XML)[CDATA]]区間]]宣言という素晴らしい出力をしてくれます(w [[#comment]] ** 不思議解釈 [34] [CODE(HTMLa)[src]] 属性のある [CODE(HTMLe)[script]] の中に [CODE(HTMLe)[noscript]] を書く困った人がいます。。。 ([[名無しさん]] [WEAK[2004-09-14 07:54:57 +00:00]]) [17] 仕様によれば (>>4)、 [CODE(HTMLa)[src]] 属性があるとき UA は内容を無視しなければなりません。この規定に特に条件は無いようなので、 スクリプト未対応の UA であっても同様でしょう。 ですから、 [CODE(HTMLe)[script]] の中に [CODE(HTMLe)[noscript]] を書くと、 HTML 4 対応の [CODE(HTMLe)[script]] 未対応 UA には無視されてしまうはずです。 [[#comment]] ** 他との関係 [3] [[ASP]] などの鯖側で HTML 文書 (もどき) を前処理する類のシステムの一部では、 [CODE(HTMLe)[script]] 要素 (のようなもの) を拡張して、 [CODE[[[runat]]]] 属性などを付与して鯖側で実行するものと [CODE(HTMLe)[script]] 要素としてクライアントに送信するものを区別していることがあります。 (そのような実現方法は開発者がスクリプトの実行を正しく把握しづらくなるのではないかとの懸念はあります。 その点、 [[NES]] のように [CODE[[[server]]]] 要素型という別の要素型を用意するのは一つの考えではありますが、 どんぐりのせいくらべといったところでしょう。) [13] スクリプトによって HTML 文書を動的に扱う方法として、 [[JavaScript]] の [CODE(js)[[[document]].[[write]]]] がよく使われました。 ([CODE(js)[document.write]] は後に [[DOM 1]] で [CODE(DOMi)[[[HTMLDocument]]]] 界面の [CODE(DOMm)[[[write]]]] method として標準化されています。) HTML 4 仕様書は読み込み時のスクリプトによる文書に書き換えについても規定していますが、 その内容は [CODE(js)[document.write]] (と同様なもの) を想定しているようです。実際に使われていたのも [CODE(js)[document.write]] (と同様なもの) だけでしょう。というわけで、 [CODE(DOMm)[[[write]]]] method の説明もご覧ください。 [39] スクリプトに対応していなかったり、実行しないことにしていたりするときの[[代替内容]]を提供する [CODE(HTMLe)[[[noscript]]]] が用意されています。アクセス可能性の確保のために、 重要な情報を提供する [CODE(HTMLe)[script]] は、 対応する [CODE(HTMLe)[noscript]] 要素を用意しておくことが極めて望ましいと考えられます。 [[#comment]] ** 例 [37] 二乗した結果を書き出す例 [SRC[HTML 4 18.3.2 改]] [[JavaScript]] による例 [PRE(HTML)[ ]PRE] [[VBScript]] による例 [PRE(HTML)[ ]PRE] [[Tcl]] による例 [PRE(HTML)[ ]PRE] [[#comment]] ** メモ [[#comment]] * script 要素 (ASP) [[#comment]] ** 属性 ,HTML (>>9) に加えて、 ,== ,== ,== ,runat ,server ,なし ,動作場所 >>5 [5] [CODE[runat]] は、 [[M$]] の [[ASP]] で使われて、値が [CODE["server"]] である場合に、その要素のスクリプトはサーバーで処理されます。 (クライアントには送られません。) この属性は [[W3C]] の規格では規定されていません。サーバーで処理される以外で使ってはいけません。 - [6] >>2-3,>>5 [CODE[language]] 属性や [CODE[type]] 属性を省略しても [CODE[<%@ Page Language="VB" %>]] みたいのが書いてあれば、それ以降の部分で解釈されるサーバー側スクリプトはその言語で解釈されるそうです。 - [7] >>5-6 それから、 [CODE[runat]] 属性はどんな要素にも? 使えて、サーバー側スクリプトからアクセス可能なことを表す?らしいです。全くもって理解不能な世界ですが。。。 - [8] >>2 ASP での既定値は (設定ファイルで変更しない限り) [CODE[VB]] (= [[VBScript]]) だそうです。 [[#comment]] * script 要素型 (CSP) - [10] CSP の script 要素では runat="server"/"compiler" の属性があります。 ''Introduction to Cache Server Pages - The CSP Compiler'' - [11] このほか CSP の script 要素には色んな独自拡張属性 (もしかして自由に作れる?) があります。 ''技術サポート'' [[#comment]] * msxsl:script 要素 (M$XML の XSLT 実装) [21] [CODE(XML)[{urn:schemas-microsoft-com:xslt}:script]] 要素を使うと、 [[XSLT]] (の [[XPath]] を使う文脈) で利用者定義の関数を使用することが可能となります。 親要素は xslt:[[stylesheet]] 要素又は xslt:[[transform]] 要素です。内容は #[[PCDATA]] です (たぶん)。 ,implements-prefix ,名前空間接頭辞 ,必須 ,関数の名前空間 ,language ,html:[[language]] と同じ ,不明 ,スクリプト言語 [[language]] 属性には [CODE(HTML)[html:script]] 要素の場合と同じ値を指定できるそうです。 [CODE(XML)[implements-prefix]] 属性には、 XSLT 側で関数を呼ぶ際の [[XML名前空間]]接頭辞を与えます。 この値は自分以上の要素の [[xmlns]] 属性を使って宣言されていなければならないはずです。 [22] 言葉で説明するより実例を見たほうが分かりやすいでしょう。 [PRE[ function bar (baz) { return baz; } ]PRE] この場合は関数 [CODE(XPath)[foo:bar(baz)]] は引数 [CODE(JS)[baz]] をただ返すだけの何の面白味もないものですが、 雰囲気はつかめるでしょう。 - ''XSLT Elements'' [[#comment]] - ''XSLT 1.0で正規表現を使う(MSXML限定)'' [[#comment]] * xalan:script 要素 (Xalan-Java XSLT 実装) [23] [[Xalan]] では [[XSLT]] [[スタイル・シート]]で [[JavaScript]] などを使うのに [CODE(XML)[xalan:script]] 要素を使います。 親要素は xalan:[[component]] 要素です。 ,lang ,CDATA ,必須 ,スクリプト言語 ,src ,[[URI]] ,(指定なし) ,外部スクリプト参照 [[HTML]] や MSXML での書き方と互換性はありません。 - ''Xalan-Java Extensions'' [[#comment]] * メモ