1. 4.12 スクリプティング
      1. 4.12.1 script要素
        1. 4.12.1.1 Processing model
        2. 4.12.1.2 スクリプト言語
        3. 4.12.1.3 script要素のコンテンツの制約
        4. 4.12.1.4 外部スクリプトに対するインライン文書
        5. 4.12.1.5 Interaction of script elements and XSLT
      2. 4.12.2 noscript要素
      3. 4.12.3 template要素
        1. 4.12.3.1 Interaction of template elements with XSLT and XPath
      4. 4.12.4 slot要素

4.12 スクリプティング

スクリプトは著者が文書に双方向性を追加することを許可する。

著者は、宣言型のメカニズムがしばしばより保守しやすく、かつ多くのユーザーがスクリプトを無効としているため、可能であれば、スクリプトに宣言型の代替を使用するよう推奨される。

たとえば、より詳細な情報を表示するセクションを表示または非表示にするスクリプトを使用する代わりに、details要素を使用できる。

著者はまた、スクリプトのサポートがない状態でそれらのアプリケーションが行儀よくデグレードするよう推奨される。

たとえば、著者がテーブルヘッダーにおいてリンクに動的なテーブルの再ソートを提供する場合、リンクはまたサーバーからソートされたテーブルを要求することによって、スクリプトなしで機能させることができるかもしれない。

4.12.1 script要素

カテゴリー
メタデータコンテンツ
フローコンテンツ
フレージングコンテンツ
スクリプトサポート要素
この要素を使用できるコンテキスト
メタデータコンテンツが期待される場所。
フレージングコンテンツが期待される場所。
スクリプトサポート要素が期待される場所。
コンテンツモデル
src属性が存在しない場合、type属性の値に依存するが、スクリプトの内容制限に一致しなければならない。
src属性が存在する場合、要素は空またはスクリプト文書を含むだけでなくスクリプトの内容制限に一致するかのいずれかでなければならない。
text/htmlにおけるタグ省略
どちらのタグも省略不可。
コンテンツ属性
グローバル属性
src — リソースのアドレス
type — 埋め込みリソースタイプ
nomodule — Prevents execution in user agents that support module scripts
charset — 外部スクリプトリソースの文字エンコーディング
async — ブロックなしで、可能な場合にスクリプトを実行する
defer — スクリプトの実行を延期する
crossorigin — 要素がcrossorigin要求を処理する方法
nonceContent Security Policyチェックで使用される暗号nonce [CSP]
integritySubresource Integrityチェックで使用される整合性メタデータ[SRI]
DOMインターフェイス
[HTMLConstructor]
interface HTMLScriptElement : HTMLElement {
  [CEReactions] attribute USVString src;
  [CEReactions] attribute DOMString type;
  [CEReactions] attribute boolean noModule;
  [CEReactions] attribute DOMString charset;
  [CEReactions] attribute boolean async;
  [CEReactions] attribute boolean defer;
  [CEReactions] attribute DOMString? crossOrigin;
  [CEReactions] attribute DOMString text;
  [CEReactions] attribute DOMString nonce;
  [CEReactions] attribute DOMString integrity;

};

script要素は、著者が文書に動的スクリプトおよびデータブロックを含むことを許可する。この要素は、ユーザーにコンテンツを表すものでない。

type属性は、表されるスクリプトの型をカスタマイズを可能にする:

データブロック妥当なMIMEタイプを使用して表記されなければならない要件は、潜在的な将来の衝突を回避するための場所である。この仕様がスクリプトの追加の型をいずれ追加する場合、その追加の型は"module"値がモジュールスクリプトを表す方法のように、MIMEタイプでない何かにtype属性を設定することによってトリガーされる。現在に妥当なMIMEタイプを使用することで、将来のユーザーエージェントでさえも、データブロックが異なるスクリプトタイプとして再解釈されないことを保証する。

クラシックスクリプトおよびモジュールスクリプトは、インラインで埋め込まれるか、指定された場合に使用する外部スクリプトリソースのURLを与える、src属性を使用する外部ファイルからインポートされるかのいずれかであってもよい。srcが指定される場合、潜在的にスペースで囲まれる妥当な空でないURLでなければならない。インラインscript要素、または外部スクリプトリソースのコンテンツは、それぞれクラシックスクリプトおよびモジュールスクリプトに対するJavaScript仕様のScriptまたはModule制作物の要件に適合しなければならない。[JAVASCRIPT]

データブロックを含めるために使用される場合、データは、インラインに埋め込まれなければならず、データの形式は、type属性を使用して指定しなければならず、かつscript要素のコンテンツは、使用される形式のために定義される要件に適合しなければならない。srccharsetasyncnomoduledefercrossoriginnonceおよびintegrity属性を指定してはならない。

The nomodule attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts. This allows selective execution of module scripts in modern user agents and classic scripts in older user agents, as shown below. The nomodule attribute must not be specified on module scripts (and will be ignored if it is).

charset属性は、外部スクリプトリソースの文字エンコーディングを与える。src属性が存在しない場合、またはスクリプトがクラシックスクリプトでない場合、属性は指定してはならない。(モジュールスクリプトは常にUTF-8として解釈される。)属性が設定される場合、その値はエンコーディングラベルのいずれかとASCII大文字・小文字不区別で一致しなければならず、かつもしあれば、外部ファイルのContent-Typeメタデータcharsetパラメーターと同じエンコーディングを指定しなければならない。[ENCODING]

asyncおよびdefer属性は、どのようにスクリプトが評価されるべきかを示す真偽属性である。クラシックスクリプトdeferまたはasyncを指定してもよい。モジュールスクリプトは、asyncを指定してもよい。src属性が存在しない場合、deferおよびasync属性は指定されてはならない。

Support: script-deferChrome for Android 59+Chrome 8+UC Browser for Android 11.4+iOS Safari 5.0+Firefox 3.5+IE 10+Samsung Internet 4+Opera Mini NoneSafari 5+Edge 12+Android Browser 3+Opera 15+

Source: caniuse.com

Support: script-asyncChrome for Android 59+Chrome 8+UC Browser for Android 11.4+iOS Safari 5.0+Firefox 3.6+IE 10+Samsung Internet 4+Opera Mini NoneSafari 5.1+Edge 12+Android Browser 3+Opera 15+

Source: caniuse.com

これらの属性を使用して、スクリプトの種類によって選択できる複数の可能なモードが存在する。

クラシックスクリプトについて、async属性が存在する場合、クラシックスクリプトは、構文解析と並行してフェッチされるとすぐに(潜在的に構文解析が完了する前に)利用可能になると評価される。asyncが存在しないがdefer属性が存在する場合、クラシックスクリプトは、並行してフェッチされ、ページが解析終了した際に評価される。いずれの属性も存在しない場合、スクリプトは、両方が完了するまで解析を阻止して、すぐにフェッチされ評価される。

モジュールスクリプトについて、async属性が存在する場合、モジュールスクリプトとそのすべての依存関係は、構文解析と並行してフェッチされ、モジュールスクリプトは利用可能になるとすぐに(潜在的に構文解析が完了する前に)評価される。そうでなければ、モジュールスクリプトとその依存関係は、構文解析と並行してフェッチされ、ページが解析終了した際に評価される。(defer属性は、モジュールスクリプトに影響しない。)

これは、次の模式図にすべて要約される:

<script>のために、解析はフェッチと実行によって中断される。With <script defer>, fetching is parallel to parsing and execution takes place after all parsing has finished. And with <script async>, fetching is parallel to parsing but once it finishes parsing is interrupted to execute the script. The story for <script type="module"> is similar to <script defer>, but the dependencies will be fetched as well, and the story for <script type="module" async> is similar to <script async> with the extra dependency fetching.

これら属性の正確な処理の詳細は、主に歴史的な理由から、いくぶん自明でない、多くのHTMLの側面を含む。したがって、実装要求は必然的に仕様のあらゆる場所に散在している。(この節の)下記のアルゴリズムは、この処理の中核を説明するが、これらのアルゴリズムが参照する、およびHTMLにおけるscript開始タグと終了タグに対する構文解析規則、無関係なコンテンツでXMLでdocument.write()メソッドに対する規則、スクリプトの取り扱いなどによって参照される。

たとえasync属性が指定されても、デフォルトとなるブロッキング動作の代わりにdeferの動作をフォールバックするために、deferのみをサポートする(かつasyncをサポートしない)レガシーウェブブラウザーをもたらすため、defer属性は指定されてもよい。

crossorigin属性はCORS設定属性である。クラシックスクリプトについて、スクリプトが他の生成元から得られる場合、エラー情報が公開されるかどうかを制御する。モジュールスクリプトについて、クロスオリジンのリクエストに使用される資格情報モードを制御する。

クラシックスクリプトとは異なり、モジュールスクリプトは、クロスオリジンフェッチのためにCORSプロトコルを使用する必要がある。

nonce属性は、要素で指定されるスクリプトが実行されるかどうかを判断するためにコンテンツセキュリティポリシーで使用することができる暗号ノンス("一度使用される数字")を表す。値はテキストである。[CSP]

integrity属性は、この要素が責任を負うリクエストに対する完全性メタデータを表す。値はテキストである。The integrity attribute must not be specified when embedding a module script or when the src attribute is not specified. [SRI]

srctypecharsetnomoduleasyncdefercrossoriginnonceintegrityの各属性を動的に変更することは直接的な効果はない。これらの属性は、後述する特定の時間にのみ使用される。

The IDL attributes src, type, charset, defer, integrity, and nonce, must each reflect the respective content attributes of the same name.

crossOrigin IDL属性は、crossoriginコンテンツ属性を反映しなければならない。

The noModule IDL attribute must reflect the nomodule content attribute.

The async IDL attribute controls whether the element will execute asynchronously or not. If the element's "non-blocking" flag is set, then, on getting, the async IDL attribute must return true, and on setting, the "non-blocking" flag must first be unset, and then the content attribute must be removed if the IDL attribute's new value is false, and must be set to the empty string if the IDL attribute's new value is true. If the element's "non-blocking" flag is not set, the IDL attribute must reflect the async content attribute.

script . text [ = value ]

要素の子テキストコンテンツを返す。

与えられた値を持つ要素の子を置換するために、設定できる。

The IDL attribute text must return the child text content of the script element. 設定する際に、それはtextContent IDL属性と同じように振る舞わなければならない。

document.write()メソッドを使用して挿入するとき、通常はscript要素が実行される(一般に、スクリプトの実行またはHTMLの解析をブロックする)。innerHTML属性とouterHTML属性を使用して挿入する場合、それらは一切実行されない。

次の例において、2つのscript要素が使用される。1つは外部のクラシックスクリプトを埋め込み、もう1つはデータブロックのようないくつかのデータを含む。

<script src="game-engine.js"></script>
<script type="text/x-game-map">
........U.........e
o............A....e
.....A.....AAA....e
.A..AAA...AAAAA...e
</script>

この場合のデータは、ビデオゲームのマップを生成するスクリプトによって使用されるかもしれない。しかし、データはそのように使用する必要はない。おそらく実際にマップデータは、ページのマークアップの他の部分に埋め込まれており、ここでデータブロックは、ゲームマップで特定の機能を探しているユーザーを支援するサイトの検索エンジンによって単に使用される。

次のサンプルは、script要素が外部モジュールスクリプトを含めるために使用される方法を示す。また、フォームの出力を初期化する場合に、文書が解析されている間にscript要素がスクリプトを呼び出すために使用されうる方法を示す。

<script>
 function calculate(form) {
   var price = 52000;
   if (form.elements.brakes.checked)
     price += 1000;
   if (form.elements.radio.checked)
     price += 2500;
   if (form.elements.turbo.checked)
     price += 5000;
   if (form.elements.sticker.checked)
     price += 250;
   form.elements.result.value = price;
 }
</script>
<form name="pricecalc" onsubmit="return false" onchange="calculate(this)">
 <fieldset>
  <legend>Work out the price of your car</legend>
  <p>Base cost: £52000.</p>
  <p>Select additional options:</p>
  <ul>
   <li><label><input type=checkbox name=brakes> Ceramic brakes (£1000)</label></li>
   <li><label><input type=checkbox name=radio> Satellite radio (£2500)</label></li>
   <li><label><input type=checkbox name=turbo> Turbo charger (£5000)</label></li>
   <li><label><input type=checkbox name=sticker> "XZ" sticker (£250)</label></li>
  </ul>
  <p>Total: £<output name=result></output></p>
 </fieldset>
 <script>
  calculate(document.forms.pricecalc);
 </script>
</form>

次のサンプルは、script要素が外部モジュールスクリプトを含めるために使用される方法を示す。

<script type="module" src="app.js"></script>

このモジュール、およびそのすべての依存関係(ソースファイル内のJavaScript import文を通して表現される)は、フェッチされる。一度、全体の結果としてモジュールツリーがインポートされ、かつ文書が解析を完了したら、app.jsのコンテンツは評価される。

さらに、同じWindow内の他のscript要素からのコードがapp.jsからモジュールをインポートする場合(たとえばimport "./app.js";経由で)、より早いscript要素によって作成された同じモジュールスクリプトがインポートされる。

This example shows how to include a module script for modern user agents, and a classic script for older user agents:

<script type="module" src="app.js"></script>
<script nomodule src="classic-app-bundle.js"></script>

In modern user agents that support module scripts, the script element with the nomodule attribute will be ignored, and the script element with a type of "module" will be fetched and evaluated (as a module script). Conversely, older user agents will ignore the script element with a type of "module", as that is an unknown script type for them — but they will have no problem fetching and evaluating the other script element (as a classic script), since they do not implement the nomodule attribute.

次のサンプルは、​​script要素が(たとえばニュースサイト上で)より面白い読書体験を生み出すために、文書のテキストで多数の置換を行うインラインモジュールスクリプトを書くために使用することができる方法を示す:[XKCD1288]

<script type="module">
 import { walkAllTextNodeDescendants } from "./dom-utils.js";

 const substitutions = new Map([
   ["witnesses", "these dudes I know"]
   ["allegedly", "kinda probably"]
   ["new study", "Tumblr post"]
   ["rebuild", "avenge"]
   ["space", "spaaace"]
   ["Google glass", "Virtual Boy"]
   ["smartphone", "Pokédex"]
   ["electric", "atomic"]
   ["Senator", "Elf-Lord"]
   ["car", "cat"]
   ["election", "eating contest"]
   ["Congressional leaders", "river spirits"]
   ["homeland security", "Homestar Runner"]
   ["could not be reached for comment", "is guilty and everyone knows it"]
 ]);

 function substitute(textNode) {
   for (const [before, after] of substitutions.entries()) {
     textNode.data = textNode.data.replace(new RegExp(`\\b${before}\\b`, "ig"), after);
   }
 }

 walkAllTextNodeDescendants(document.body, substitute);
</script>

モジュールスクリプトを使用して得られたいくつかの注目すべき機能は、他のJavaScriptモジュール、デフォルトでstrictモード、およびトップレベル宣言がグローバルオブジェクトに新しいプロパティを導入しない方法から関数をインポートする機能を含む。両方の文書の解析が完了し、およびその依存関係(dom-utils.js)がフェッチされかつ評価されるまで、このscript要素が文書に表示されるかを問わず、評価されないことにも注意する。

4.12.1.1 Processing model

A script element has several associated pieces of state.

The first is a flag indicating whether or not the script block has been "already started". Initially, script elements must have this flag unset (script blocks, when created, are not "already started"). The cloning steps for script elements must set the "already started" flag on the copy if it is set on the element being cloned.

The second is a flag indicating whether the element was "parser-inserted". Initially, script elements must have this flag unset. It is set by the HTML parser and the XML parser on script elements they insert and affects the processing of those elements.

The third is a flag indicating whether the element will be "non-blocking". Initially, script elements must have this flag set. It is unset by the HTML parser and the XML parser on script elements they insert. In addition, whenever a script element whose "non-blocking" flag is set has an async content attribute added, the element's "non-blocking" flag must be unset.

The fourth is a flag indicating whether or not the script block is "ready to be parser-executed". Initially, script elements must have this flag unset (script blocks, when created, are not "ready to be parser-executed"). This flag is used only for elements that are also "parser-inserted", to let the parser know when to execute the script.

The fifth is the script's type, which is either "classic" or "module". It is determined when the script is prepared, based on the type attribute of the element at that time.

The sixth is a flag indicating whether or not the script is from an external file. It is determined when the script is prepared, based on the src attribute of the element at that time.

Finally, a script element has the script's script, which is a script resulting from preparing the element. This is set asynchronously after the classic script or module tree is fetched. Once it is set, either to a script in the case of success or to null in the case of failure, the fetching algorithms will note that the script is ready, which can trigger other actions. The user agent must delay the load event of the element's node document until the script is ready.


When a script element that is not marked as being "parser-inserted" experiences one of the events listed in the following list, the user agent must immediately prepare the script element:

To prepare a script, the user agent must act as follows:

  1. If the script element is marked as having "already started", then abort these steps at this point. The script is not executed.

  2. If the element has its "parser-inserted" flag set, then set was-parser-inserted to true and unset the element's "parser-inserted" flag. Otherwise, set was-parser-inserted to false.

    This is done so that if parser-inserted script elements fail to run when the parser tries to run them, e.g. because they are empty or specify an unsupported scripting language, another script can later mutate them and cause them to run again.

  3. If was-parser-inserted is true and the element does not have an async attribute, then set the element's "non-blocking" flag to true.

    This is done so that if a parser-inserted script element fails to run when the parser tries to run it, but it is later executed after a script dynamically updates it, it will execute in a non-blocking fashion even if the async attribute isn't set.

  4. If the element has no src attribute, and its child nodes, if any, consist only of comment nodes and empty Text nodes, then abort these steps at this point. The script is not executed.

  5. If the element is not connected, then abort these steps. The script is not executed.

  6. If either:

    ...let the script block's type string for this script element be "text/javascript".

    Otherwise, if the script element has a type attribute, let the script block's type string for this script element be the value of that attribute with leading and trailing ASCII whitespace stripped.

    Otherwise, the element has a non-empty language attribute; let the script block's type string for this script element be the concatenation of the string "text/" followed by the value of the language attribute.

    The language attribute is never conforming, and is always ignored if there is a type attribute present.

    Determine the script's type as follows:

  7. If was-parser-inserted is true, then flag the element as "parser-inserted" again, and set the element's "non-blocking" flag to false.

  8. Set the element's "already started" flag.

  9. If the element is flagged as "parser-inserted", but the element's node document is not the Document of the parser that created the element, then abort these steps.

  10. If scripting is disabled for the script element, then abort these steps at this point. The script is not executed.

    The definition of scripting is disabled means that, amongst others, the following scripts will not execute: scripts in XMLHttpRequest's responseXML documents, scripts in DOMParser-created documents, scripts in documents created by XSLTProcessor's transformToDocument feature, and scripts that are first inserted by a script into a Document that was created using the createDocument() API. [XHR] [DOMPARSING] [XSLTP] [DOM]

  11. If the script element has a nomodule content attribute and the script's type is "classic", then abort these steps. The script is not executed.

    This means specifying nomodule on a module script has no effect; the algorithm continues onward.

  12. If the script element does not have a src content attribute, and the Should element's inline behavior be blocked by Content Security Policy? algorithm returns "Blocked" when executed upon the script element, "script", and the script element's child text content, then abort these steps. The script is not executed. [CSP]

  13. If the script element has an event attribute and a for attribute, and the script's type is "classic", then:

    1. Let for be the value of the for attribute.

    2. Let event be the value of the event attribute.

    3. Strip leading and trailing ASCII whitespace from event and for.

    4. If for is not an ASCII case-insensitive match for the string "window", then abort these steps at this point. The script is not executed.

    5. If event is not an ASCII case-insensitive match for either the string "onload" or the string "onload()", then abort these steps at this point. The script is not executed.

  14. If the script element has a charset attribute, then let encoding be the result of getting an encoding from the value of the charset attribute.

    If the script element does not have a charset attribute, or if getting an encoding failed, let encoding be the same as the encoding of the script element's node document.

    If the script's type is "module", this encoding will be ignored.

  15. Let CORS setting be the current state of the element's crossorigin content attribute.

  16. Let module script credentials mode be determined by switching on CORS setting:

    No CORS
    "omit"
    Anonymous
    "same-origin"
    Use Credentials
    "include"
  17. If the script element has a nonce attribute, then let cryptographic nonce be that attribute's value.

    Otherwise, let cryptographic nonce be the empty string.

  18. If the script element has an integrity attribute, then let integrity metadata be that attribute's value.

    Otherwise, let integrity metadata be the empty string.

  19. Let parser state be "parser-inserted" if the script element has been flagged as "parser-inserted", and "not parser-inserted" otherwise.

  20. Let settings be the element's node document's Window object's environment settings object.

  21. If the element has a src content attribute, then:

    1. Let src be the value of the element's src attribute.

    2. If src is the empty string, queue a task to fire an event named error at the element, and abort these steps.

    3. Set the element's from an external file flag.

    4. Parse src relative to the element's node document.

    5. If the previous step failed, queue a task to fire an event named error at the element, and abort these steps. Otherwise, let url be the resulting URL record.

    6. Switch on the script's type:

      "classic"

      Fetch a classic script given url, settings, cryptographic nonce, integrity metadata, parser state, CORS setting, and encoding.

      "module"

      Fetch a module script graph given url, settings, "script", cryptographic nonce, parser state, and module script credentials mode.

      When the chosen algorithm asynchronously completes, set the script's script to the result. At that time, the script is ready.

      For performance reasons, user agents may start fetching the classic script or module tree (as defined above) as soon as the src attribute is set, instead, in the hope that the element will be inserted into the document (and that the crossorigin attribute won't change value in the meantime). Either way, once the element is inserted into the document, the load must have started as described in this step. If the UA performs such prefetching, but the element is never inserted in the document, or the src attribute is dynamically changed, or the crossorigin attribute is dynamically changed, then the user agent will not execute the script so obtained, and the fetching process will have been effectively wasted.

  22. If the element does not have a src content attribute, run these substeps:

    1. Let source text be the value of the text IDL attribute.

    2. Switch on the script's type:

      "classic"
      1. Let script be the result of creating a classic script using source text and settings.

      2. Set the script's script to script.

      3. The script is ready.

      "module"
      1. Let base URL be the script element's node document's document base URL.

      2. Let script be the result of creating a module script using source text, settings, base URL, cryptographic nonce, parser state, and module script credentials mode.

      3. If this returns null, set the script's script to null and abort these substeps; the script is ready.

      4. Fetch the descendants of and instantiate script, given the destination "script". When this asynchronously completes, set the script's script to the result. At that time, the script is ready.

  23. Then, follow the first of the following options that describes the situation:

    If the script's type is "classic", and the element has a src attribute, and the element has a defer attribute, and the element has been flagged as "parser-inserted", and the element does not have an async attribute
    If the script's type is "module", and the element has been flagged as "parser-inserted", and the element does not have an async attribute

    Add the element to the end of the list of scripts that will execute when the document has finished parsing associated with the Document of the parser that created the element.

    When the script is ready, set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

    If the script's type is "classic", and the element has a src attribute, and the element has been flagged as "parser-inserted", and the element does not have an async attribute

    The element is the pending parsing-blocking script of the Document of the parser that created the element. (There can only be one such script per Document at a time.)

    When the script is ready, set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

    If the script's type is "classic", and the element has a src attribute, and the element does not have an async attribute, and the element does not have the "non-blocking" flag set
    If the script's type is "module", and the element does not have an async attribute, and the element does not have the "non-blocking" flag set

    Add the element to the end of the list of scripts that will execute in order as soon as possible associated with the node document of the script element at the time the prepare a script algorithm started.

    When the script is ready, run the following steps:

    1. If the element is not now the first element in the list of scripts that will execute in order as soon as possible to which it was added above, then mark the element as ready but abort these steps without executing the script yet.

    2. Execution: Execute the script block corresponding to the first script element in this list of scripts that will execute in order as soon as possible.

    3. Remove the first element from this list of scripts that will execute in order as soon as possible.

    4. If this list of scripts that will execute in order as soon as possible is still not empty and the first entry has already been marked as ready, then jump back to the step labeled execution.

    If the script's type is "classic", and the element has a src attribute
    If the script's type is "module"

    The element must be added to the set of scripts that will execute as soon as possible of the node document of the script element at the time the prepare a script algorithm started.

    When the script is ready, execute the script block and then remove the element from the set of scripts that will execute as soon as possible.

    If the element does not have a src attribute, and the element has been flagged as "parser-inserted", and either the parser that created the script is an XML parser or it's an HTML parser whose script nesting level is not greater than one, and the Document of the HTML parser or XML parser that created the script element has a style sheet that is blocking scripts

    The element is the pending parsing-blocking script of the Document of the parser that created the element. (There can only be one such script per Document at a time.)

    Set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

    そうでなければ
    Immediately execute the script block, even if other scripts are already executing.

The pending parsing-blocking script of a Document is used by the Document's parser(s).

If a script element that blocks a parser gets moved to another Document before it would normally have stopped blocking that parser, it nonetheless continues blocking that parser until the condition that causes it to be blocking the parser no longer applies (e.g. if the script is a pending parsing-blocking script because there was a style sheet that is blocking scripts when it was parsed, but then the script is moved to another Document before the style sheet loads, the script still blocks the parser until the style sheets are all loaded, at which time the script executes and the parser is unblocked).

When the user agent is required to execute a script block, it must run the following steps.

  1. If the element is flagged as "parser-inserted", but the element's node document is not the Document of the parser that created the element, then abort these steps.

  2. If the script's script is null, fire an event named error at the element, and abort these steps.

  3. If the script is from an external file, or the script's type is "module", then increment the ignore-destructive-writes counter of the script element's node document. Let neutralized doc be that Document.

  4. Let old script element be the value to which the script element's node document's currentScript object was most recently set.

  5. Switch on the script's type:

    "classic"
    1. If the script element's root is not a shadow root, then set the script element's node document's currentScript attribute to the script element. Otherwise, set it to null.

      This does not use the in a document tree check, as the script element could have been removed from the document prior to execution, and in that scenario currentScript still needs to point to it.

    2. Run the classic script given by the script's script.

    "module"
    1. Set the script element's node document's currentScript attribute to null.

    2. Run the module script given by the script's script.

  6. Set the script element's node document's currentScript attribute to old script element.

  7. Decrement the ignore-destructive-writes counter of neutralized doc, if it was incremented in the earlier step.

  8. If the script is from an external file, then fire an event named load at the script element.

4.12.1.2 スクリプト言語

JavaScript MIMEタイプは、次のいずれかであるMIMEタイプの文字列であり、JavaScriptを指す[JAVASCRIPT]

ユーザーエージェントは、すべてのJavaScript MIMEタイプを認識しなければならない。

User agents may support other MIME types for other languages, but must not support other MIME types for the languages in the list above. User agents are not required to support JavaScript. The processing model for languages other than JavaScript is outside the scope of this specification.

The following MIME types (with or without parameters) must not be interpreted as scripting languages:

These types are explicitly listed here because they are poorly-defined types that are nonetheless likely to be used as formats for data blocks, and it would be problematic if they were suddenly to be interpreted as script by a user agent.

When examining types to determine if they represent supported languages, user agents must not ignore MIME parameters. Types are to be compared including all parameters.

For example, types that include the charset parameter will not be recognized as referencing any of the scripting languages listed above.

4.12.1.3 Restrictions for contents of script elements

この節で説明される多少奇妙な制約を回避する最も簡単で安全な方法は、以下のシーケンスが(たとえば文字列、正規表現、またはコメントなど)スクリプト内でリテラルに表示され、かつ式の中でこのような構造体を使用してコードを記述を避けるようにする際に、"<!--"を"<\!--"として、"<script"を"<\script"として、および"</script"を"<\/script"として常にエスケープすることである。この節の制限がトリガーになりやすい落とし穴を回避する:すなわち、歴史的な理由のために、HTMLにおけるscriptブロックの解析は、これらのシーケンスを考えた場合に直観的でない働きをする奇妙で風変わりな慣習である。

script要素のtextContentは、Unicodeである文字セットである、以下のABNFでscript生成物と対等でなければならない。[ABNF]

script        = outer *( comment-open inner comment-close outer )

outer         = < any string that doesn't contain a substring that matches not-in-outer >
not-in-outer  = comment-open
inner         = < any string that doesn't contain a substring that matches not-in-inner >
not-in-inner  = comment-close / script-open

comment-open  = "<!--"
comment-close = "-->"
script-open   = "<" s c r i p t tag-end

s             =  %x0053 ; U+0053 LATIN CAPITAL LETTER S
s             =/ %x0073 ; U+0073 LATIN SMALL LETTER S
c             =  %x0043 ; U+0043 LATIN CAPITAL LETTER C
c             =/ %x0063 ; U+0063 LATIN SMALL LETTER C
r             =  %x0052 ; U+0052 LATIN CAPITAL LETTER R
r             =/ %x0072 ; U+0072 LATIN SMALL LETTER R
i             =  %x0049 ; U+0049 LATIN CAPITAL LETTER I
i             =/ %x0069 ; U+0069 LATIN SMALL LETTER I
p             =  %x0050 ; U+0050 LATIN CAPITAL LETTER P
p             =/ %x0070 ; U+0070 LATIN SMALL LETTER P
t             =  %x0054 ; U+0054 LATIN CAPITAL LETTER T
t             =/ %x0074 ; U+0074 LATIN SMALL LETTER T

tag-end       =  %x0009 ; U+0009 CHARACTER TABULATION (tab)
tag-end       =/ %x000A ; U+000A LINE FEED (LF)
tag-end       =/ %x000C ; U+000C FORM FEED (FF)
tag-end       =/ %x0020 ; U+0020 SPACE
tag-end       =/ %x002F ; U+002F SOLIDUS (/)
tag-end       =/ %x003E ; U+003E GREATER-THAN SIGN (>)

script要素がスクリプト文書を含む場合、以下の節で記述されるように、要素のコンテンツのさらなる制約がある。

以下のスクリプトは、この問題を示している。このように、文字列が含まれているスクリプトがあるとする:

var example = 'Consider this string: <!-- <script>';
console.log(example);

これがscriptブロックで直接この文字列を入れていた場合、上記の制限に違反しない。

<script>
  var example = 'Consider this string: <!-- <script>';
  console.log(example);
</script>

しかし、より大きな問題かつ、スクリプトがそれらの制限に違反しない理由は、実際にスクリプトが奇妙に解析されるだろうということである。上記のスクリプトブロックは終了していない。それは、実際には依然としてscriptブロックの一部であるこのスニペットにおいて"</script>"終了タグのように見えるものである。(スクリプトが終了していないため)スクリプトは実行しない。スクリプトが何らかの形で実行した場合、以下のようにマークアップが見えた場合、(ここで強調される)スクリプトが妥当なJavaScriptでないので、スクリプトは失敗するだろう:

<script>
  var example = 'Consider this string: <!-- <script>';
  console.log(example);
</script>
<!-- despite appearances, this is actually part of the script still! -->
<script>
 ... // this is the same script block still...
</script>

ここで起こっていることはレガシーな理由のために、HTMLにおけるscript要素で"<!--"および"<script"文字列は、パーサがブロックを閉じる検討するためにバランスをとる必要がある。

この節の最初に述べたように、問題の文字列をエスケープすることによって、問題は完全に回避されている:

<script>
  var example = 'Consider this string: <\!-- <\script>';
  console.log(example);
</script>
<!-- this is just a comment between script blocks -->
<script>
 ... // this is a new script block
</script>

次の例のように、これらのシーケンスは自然にスクリプト式で出現可能である:

if (x<!--y) { ... }
if ( player<script ) { ... }

このような場合、文字はエスケープすることはできないが、シーケンスが発生しないように式は次のように書き換えることができる:

if (x < !--y) { ... }
if (!--y > x) { ... }
if (!(--y) > x) { ... }
if (player < script) { ... }
if (script > player) { ... }

これを行うとはまた、同様に様々な落とし穴を回避する:関連する歴史的な理由のために、クラシックスクリプトで文字列"<!--"は、"//"のように、実際には行コメントの開始として扱われる。

4.12.1.4 Inline documentation for external scripts

script要素のsrc属性が指定される場合、もしあれば、script要素のコンテンツは、要素のコンテンツから分割されるようなtext IDL属性値でなければならず、文字セットがUnicodeである下記のABNFでdocumentation生成物と一致しなければならない。[ABNF]

documentation = *( *( space / tab / comment ) [ line-comment ] newline )
comment       = slash star *( not-star / star not-slash ) 1*star slash
line-comment  = slash slash *not-newline

; characters
tab           = %x0009 ; U+0009 CHARACTER TABULATION (tab)
newline       = %x000A ; U+000A LINE FEED (LF)
space         = %x0020 ; U+0020 SPACE
star          = %x002A ; U+002A ASTERISK (*)
slash         = %x002F ; U+002F SOLIDUS (/)
not-newline   = %x0000-0009 / %x000B-10FFFF
                ; a scalar value other than U+000A LINE FEED (LF)
not-star      = %x0000-0029 / %x002B-10FFFF
                ; a scalar value other than U+002A ASTERISK (*)
not-slash     = %x0000-002E / %x0030-10FFFF
                ; a scalar value other than U+002F SOLIDUS (/)

これは、JavaScriptのコメントで要素のコンテンツを設置するものと一致する。

この要求は、script要素のコンテンツの構文上に先の制約に加えて存在する。

以下は、依然として外部スクリプトファイルを参照する間に文書内で、著者がライセンス情報やAPI情報のような文書を含むことを許可する。src属性を提供する一方で、偶然にも著者が有効なスクリプトのように見えるものが含まないように、構文は制約される。

<script src="cool-effects.js">
 // create new instances using:
 //    var e = new Effect();
 // start the effect using .play, stop using .stop:
 //    e.play();
 //    e.stop();
</script>
4.12.1.5 Interaction of script elements and XSLT

この節は非規範的である。

This specification does not define how XSLT interacts with the script element. However, in the absence of another specification actually defining this, here are some guidelines for implementors, based on existing implementations:

The main distinction between the first two cases and the last case is that the first two operate on Documents and the last operates on a fragment.

4.12.2 noscript要素

カテゴリー
メタデータコンテンツ
フローコンテンツ
フレージングコンテンツ
この要素を使用できるコンテキスト
先祖noscript要素が存在しない場合、HTML文書head要素内。
先祖noscript要素が存在しない場合、HTML文書フレージングコンテンツが期待される場所。
コンテンツモデル
スクリプトが無効の場合、head要素内で:任意の順で、0個以上のlink要素、ゼロ個以上のstyle要素、0個以上のmeta要素。
スクリプトが無効の場合、head要素外で:透過的。ただし、noscript要素の子孫を持ってはならない。
そうでなければ:文で与えられる要件に適合するテキスト。
text/htmlにおけるタグ省略
どちらのタグも省略不可。
コンテンツ属性
グローバル属性
DOMインターフェイス
HTMLElementを使用する。

noscript要素は、スクリプトが有効である場合は何も表さず、スクリプトが無効である場合は要素の子を表す。これは、文書が解析される方法に影響を与えることによって、スクリプトをサポートするユーザーエージェントとサポートしないユーザーエージェントに異なるマークアップを提示するために使用される。

HTML文書で使用する場合、許可されるコンテンツモデルは次のとおり:

スクリプトが無効である場合、head要素内のnoscript要素に対して

noscript要素は、linkstyle、およびmeta要素のみを含まなければならない。

スクリプトが有効である場合、head要素内のnoscript要素に対して

noscript要素は、テキストのみを含まなければならない。ただし、context要素としてnoscript要素をもつHTML断片解析アルゴリズムを呼び出すものかつinputのようなテキストコンテンツがnoscript要素の子であった場合、linkstylemeta要素のみからなるノードのリストをもたらさなければならない場合を除く。そして解析エラーでない。

スクリプトが無効である場合、head要素外のnoscript要素に対して

noscript要素のコンテンツモデルは透過的であり、同時にnoscript要素がnoscript要素を持ってはならない(noscript要素を入れ子にできない)追加制限がある。

スクリプトが有効である場合、head要素外のnoscript要素に対して

noscript要素はテキストのみを含まなければならない。ただしテキストは、以下のアルゴリズムがnoscript要素およびscript要素をもたない適合文書をもたらすものでなければならず、アルゴリズムでステップは例外を投げるまたはHTMLパーサ解析エラーを起こさないようにしなければならない:

  1. 文書からすべてのscript要素を取り除く。
  2. 文書においてすべてのnoscript要素のリストを作る。そのリストの各noscript要素に対して、以下のステップを実行する:
    1. snoscript要素要素の子テキストコンテンツとする。
    2. noscript要素のouterHTML属性をsの値に設定する。(これは、副作用としてnoscript要素を文書から除去させる。)[DOMPARSING]

歴史的な理由により、パーサが呼び出されたときにスクリプトが有効にされたかどうかに基づくHTMLパーサによってnoscript要素が異なる方法で処理されるので、これらのすべてのこじつけが必要とされる。

noscriptXML文書で使用してはならない。

noscript要素はHTML構文でのみ有効だが、XML構文では効果がない。スクリプトが有効である場合、この要素が動作する方法は、基本的にパーサを"オフ"にすることであり、要素の内容は、実際の要素としてではなく純粋にテキストとして扱われているのである。XMLは、これを実行するためのメカニズムを定義しない。

The noscript element has no other requirements. In particular, children of the noscript element are not exempt from form submission, scripting, and so forth, even when scripting is enabled for the element.

次の例において、noscript要素は、スクリプトのフォールバックを提供するために使用される。

<form action="calcSquare.php">
 <p>
  <label for=x>Number</label>:
  <input id="x" name="x" type="number">
 </p>
 <script>
  var x = document.getElementById('x');
  var output = document.createElement('p');
  output.textContent = 'Type a number; it will be squared right then!';
  x.form.appendChild(output);
  x.form.onsubmit = function () { return false; }
  x.oninput = function () {
    var v = x.valueAsNumber;
    output.textContent = v + ' squared is ' + v * v;
  };
 </script>
 <noscript>
  <input type=submit value="Calculate Square">
 </noscript>
</form>

スクリプトが無効である場合、ボタンは、サーバー側で計算を行うために表示される。スクリプトが有効である場合、代わりに値がその場で計算される。

noscript要素は鈍器である。時には、スクリプトを有効にするかもしれないが、何らかの理由でページのスクリプトが失敗するかもしれない。このような理由から、次の例のように、noscript要素の使用を避ける代わりに、その場でスクリプトのないページからスクリプト化されたページにページを変更するスクリプトを設計することが一般により良い:

<form action="calcSquare.php">
 <p>
  <label for=x>Number</label>:
  <input id="x" name="x" type="number">
 </p>
 <input id="submit" type=submit value="Calculate Square">
 <script>
  var x = document.getElementById('x');
  var output = document.createElement('p');
  output.textContent = 'Type a number; it will be squared right then!';
  x.form.appendChild(output);
  x.form.onsubmit = function () { return false; }
  x.oninput = function () {
    var v = x.valueAsNumber;
    output.textContent = v + ' squared is ' + v * v;
  };
  var submit = document.getElementById('submit');
  submit.parentNode.removeChild(submit);
 </script>
</form>

上記の手法は、noscriptが許可されていないため、XML文書でも役に立つ。

4.12.3 template要素

Support: templateChrome for Android 59+Chrome 35+UC Browser for Android 11.4+iOS Safari 9.0+Firefox 22+IE NoneSamsung Internet 4+Opera Mini NoneSafari 9+Edge (limited) 13+Android Browser 4.4+Opera 22+

Source: caniuse.com

カテゴリー
メタデータコンテンツ
フローコンテンツ
フレージングコンテンツ
スクリプトサポート要素
この要素を使用できるコンテキスト
メタデータコンテンツが期待される場所。
フレージングコンテンツが期待される場所。
スクリプトサポート要素が期待される場所。
span属性を持たないcolgroup要素の子として。
コンテンツモデル
Nothing
text/htmlにおけるタグ省略
どちらのタグも省略不可。
コンテンツ属性
グローバル属性
DOMインターフェイス
[HTMLConstructor]
interface HTMLTemplateElement : HTMLElement {
  readonly attribute DocumentFragment content;
};

template要素は、複製され、スクリプトによって文書に挿入できるHTMLの断片を宣言するために使用される。

レンダリングにおいて、template要素は何も表さない。

The template contents of a template element are not children of the element itself. Instead, they are stored in a DocumentFragment associated with a different Document without a browsing context so as to avoid the template contents interfering with the main Document. (For example, this avoids form controls from being submitted, scripts from executing, and so forth.) The template contents have no conformance requirements.

たとえば、次の文書を考えてみる:

<!doctype html>
<html lang="en">
 <head>
  <title>Homework</title>
 <body>
  <template id="template"><p>Smile!</p></template>
  <script>
   let num = 3;
   const fragment = document.getElementById('template').content.cloneNode(true);
   while (num-- > 1) {
     fragment.firstChild.before(fragment.firstChild.cloneNode(true));
     fragment.firstChild.textContent += fragment.lastChild.textContent;
   }
   document.body.appendChild(fragment);
  </script>
</html>

templateにおけるp要素は、DOM内のtemplateの子ではないtemplate要素のcontent IDL属性によって返されるDocumentFragmentの子である。

スクリプトがtemplate要素のappendChild()を呼び出すと、(他の要素の場合と同様に)template要素に子要素が追加される。しかし、そのようにすることは、template要素のコンテンツモデルに違反することになる。

template . content

Returns the template contents (a DocumentFragment).

Each template element has an associated DocumentFragment object that is its template contents. When a template element is created, the user agent must run the following steps to establish the template contents:

  1. Let doc be the template element's node document's appropriate template contents owner document.

  2. Create a DocumentFragment object whose node document is doc and host is the template element.

  3. Set the template element's template contents to the newly created DocumentFragment object.

A Document doc's appropriate template contents owner document is the Document returned by the following algorithm:

  1. If doc is not a Document created by this algorithm, then:

    1. If doc does not yet have an associated inert template document, then:

      1. Let new doc be a new Document (that does not have a browsing context). This is "a Document created by this algorithm" for the purposes of the step above.

      2. If doc is an HTML document, mark new doc as an HTML document also.

      3. Let doc's associated inert template document be new doc.

    2. Set doc to doc's associated inert template document.

    Each Document not created by this algorithm thus gets a single Document to act as its proxy for owning the template contents of all its template elements, so that they aren't in a browsing context and thus remain inert (e.g. scripts do not run). Meanwhile, template elements inside Document objects that are created by this algorithm just reuse the same Document owner for their contents.

  2. Return doc.

The adopting steps (with node and oldDocument as parameters) for template elements are the following:

  1. Let doc be node's node document's appropriate template contents owner document.

    node's node document is the Document object that node was just adopted into.

  2. Adopt node's template contents (a DocumentFragment object) into doc.

The content IDL attribute must return the template element's template contents.


The cloning steps for a template element node being cloned to a copy copy must run the following steps:

  1. If the clone children flag is not set in the calling clone algorithm, abort these steps.

  2. Let copied contents be the result of cloning all the children of node's template contents, with document set to copy's template contents's node document, and with the clone children flag set.

  3. Append copied contents to copy's template contents.

この例において、スクリプトは、手動でマークアップから構造を生成する代わりに要素構造を提供するためにtemplateを使用して、データ構造からデータをもつテーブル4列に投入する。

<!DOCTYPE html>
<html lang='en'>
<title>Cat data</title>
<script>
 // Data is hard-coded here, but could come from the server
 var data = [
   { name: 'Pillar', color: 'Ticked Tabby', sex: 'Female (neutered)', legs: 3 },
   { name: 'Hedral', color: 'Tuxedo', sex: 'Male (neutered)', legs: 4 },
 ];
</script>
<table>
 <thead>
  <tr>
   <th>Name <th>Color <th>Sex <th>Legs
 <tbody>
  <template id="row">
   <tr><td><td><td><td>
  </template>
</table>
<script>
 var template = document.querySelector('#row');
 for (var i = 0; i < data.length; i += 1) {
   var cat = data[i];
   var clone = template.content.cloneNode(true);
   var cells = clone.querySelectorAll('td');
   cells[0].textContent = cat.name;
   cells[1].textContent = cat.color;
   cells[2].textContent = cat.sex;
   cells[3].textContent = cat.legs;
   template.parentNode.appendChild(clone);
 }
</script>

この例は、templateのコンテンツにcloneNode()を使用する。それは、同じことをするdocument.importNode()を等価的に使用することもできる。ノード文書が更新される際に、この2つのAPIの唯一の違いがある。ノードがappendChild()で付加される場合にcloneNode()とともに更新され、ノードがクローン化される際に、document.importNode()とともに更新される。

4.12.3.1 Interaction of template elements with XSLT and XPath

この節は非規範的である。

This specification does not define how XSLT and XPath interact with the template element. However, in the absence of another specification actually defining this, here are some guidelines for implementors, which are intended to be consistent with other processing described in this specification:

4.12.4 slot要素

カテゴリー
フローコンテンツ
フレージングコンテンツ
この要素を使用できるコンテキスト
フレージングコンテンツが期待される場所。
コンテンツモデル
透過的
text/htmlにおけるタグ省略
どちらのタグも省略不可。
コンテンツ属性
グローバル属性
name — シャドウツリースロットの名前
DOMインターフェイス
[HTMLConstructor]
interface HTMLSlotElement : HTMLElement {
  [CEReactions] attribute DOMString name;
  sequence<Node> assignedNodes(optional AssignedNodesOptions options);
};

dictionary AssignedNodesOptions {
  boolean flatten = false;
};

slot要素は、スロットを定義する。典型的にシャドウツリーに使用される。もしあれば、slot要素はその割り当てられるノード表し、そうでなければそのコンテンツを表す。

nameコンテンツ属性は、任意の文字列値を含んでもよい。これはスロット名前を表す。

slot属性は、別の要素にスロットを割り当てるために使用される:name属性をもつslot要素は、その要素がそのname属性の値と一致する値を持つslot属性を持ち、かつslot要素がその対応するslot属性値を持つルートホストを持つシャドウツリーの子である場合、任意の要素が割り当てられる名前付きスロットを作成する。

slot . name
slot名前を取得し設定することが可能である。
slot . assignedNodes()
slot割り当てられるノードを返す。
slot . assignedNodes({ flatten: true })
もしあれば、slot割り当てられるノードを返し、そうでなければslotの子を返し、かつslot要素が存在しなくなるまで、再帰的に、slot要素に遭遇するのと同じものを返す。

name IDL属性は、同じ名前のコンテンツ属性を反映しなければならない。

呼び出される場合、assignedNodes(options)メソッドは次の手順を実行しなければならない:

  1. optionsflattenメンバーの値がfalseである場合、この要素の割り当てられたノードを返す。

  2. この要素をもつfinding flattened slotablesの結果を返す。