0% found this document useful (0 votes)
12 views17 pages

Understanding HTML Script Elements

The document outlines the HTML Living Standard for scripting elements, particularly focusing on the <script> element, which allows authors to add interactivity to web documents. It emphasizes the importance of using declarative alternatives to scripting and ensuring applications degrade gracefully without scripting support. The document details various attributes of the <script> element, including 'src', 'type', 'async', and 'defer', and their effects on script execution and loading behavior.

Uploaded by

onezhaoyn
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views17 pages

Understanding HTML Script Elements

The document outlines the HTML Living Standard for scripting elements, particularly focusing on the <script> element, which allows authors to add interactivity to web documents. It emphasizes the importance of using declarative alternatives to scripting and ensuring applications degrade gracefully without scripting support. The document details various attributes of the <script> element, including 'src', 'type', 'async', and 'defer', and their effects on script execution and loading behavior.

Uploaded by

onezhaoyn
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

HTML

Living Standard — Last Updated 21 December 2021


← 4.11 Interactive elements — Table of Contents — 4.12.5 The canvas element →

4.12 Scripting
4.12.1 The script element
[Link] Processing model
[Link] Scripting languages
[Link] Restrictions for contents of script elements
[Link] Inline documentation for external scripts
[Link] Interaction of script elements and XSLT
4.12.2 The noscript element
4.12.3 The template element
[Link] Interaction of template elements with XSLT and XPath
4.12.4 The slot element

§ 4.12 Scripting

Scripts allow authors to add interactivity to their documents.

Authors are encouraged to use declarative alternatives to scripting where possible, as declarative mechanisms are often more maintainable, and many users disable
scripting.

Example
For example, instead of using a script to show or hide a section to show more details, the details element could be used.

Authors are also encouraged to make their applications degrade gracefully in the absence of scripting support.

Example
For example, if an author provides a link in a table header to dynamically resort the table, the link could also be made to function without scripts by requesting
the sorted table from the server.

✔ MDN
§ 4.12.1 The script element

Categories:
✔ MDN
Metadata content.
Flow content.
Phrasing content.
Script-supporting element.

Contexts in which this element can be used:


Where metadata content is expected.
Where phrasing content is expected.
Where script-supporting elements are expected.

Content model:
If there is no src attribute, depends on the value of the type attribute, but must match script content restrictions.
If there is a src attribute, the element must be either empty or contain only script documentation that also matches script content restrictions.

Tag omission in text/html:


Neither tag is omissible.

Content attributes:
Global attributes
src — Address of the resource
type — Type of script
nomodule — Prevents execution in user agents that support module scripts
async — Execute script when available, without blocking while fetching
defer — Defer script execution
crossorigin — How the element handles crossorigin requests
integrity — Integrity metadata used in Subresource Integrity checks [SRI]
referrerpolicy — Referrer policy for fetches initiated by the element

Accessibility considerations:
For authors.
For implementers.

DOM interface:
IDL [Exposed=Window]
interface HTMLScriptElement : HTMLElement {
[HTMLConstructor] constructor();

[CEReactions] attribute USVString src;


[CEReactions] attribute DOMString type;
[CEReactions] attribute boolean noModule;
[CEReactions] attribute boolean async;
[CEReactions] attribute boolean defer;
[CEReactions] attribute DOMString? crossOrigin;
[CEReactions] attribute DOMString text;
[CEReactions] attribute DOMString integrity;
[CEReactions] attribute DOMString referrerPolicy;

static boolean supports(DOMString type);

// also has obsolete members


};

✔ MDN
The script element allows authors to include dynamic script and data blocks in their documents. The element does not represent content for the user.

The type attribute allows customization of the type of script represented:

Omitting the attribute, setting it to the empty string, or setting it to a JavaScript MIME type essence match, means that the script is a classic script, to be
interpreted according to the JavaScript Script top-level production. Classic scripts are affected by the async and defer attributes, but only when the src
attribute is set. Authors should omit the type attribute instead of redundantly setting it.

Setting the attribute to an ASCII case-insensitive match for the string "module" means that the script is a JavaScript module script, to be interpreted
according to the JavaScript Module top-level production. Module scripts are not affected by the defer attribute, but are affected by the async attribute
(regardless of the state of the src attribute).

Setting the attribute to any other value means that the script is a data block, which is not processed. None of the script attributes (except type itself) have
any effect on data blocks. Authors must use a valid MIME type string that is not a JavaScript MIME type essence match to denote data blocks.

Note
The requirement that data blocks must be denoted using a valid MIME type string is in place to avoid potential future collisions. If this specification ever adds
additional types of script, they will be triggered by setting the type attribute to something which is not a MIME type, like how the "module" value denotes module
scripts. By using a valid MIME type string now, you ensure that your data block will not ever be reinterpreted as a different script type, even in future user agents.

Classic scripts and JavaScript module scripts can be embedded inline, or be imported from an external file using the src attribute, which if specified gives the URL
of the external script resource to use. If src is specified, it must be a valid non-empty URL potentially surrounded by spaces.

The contents of inline script elements, or the external script resource, must conform with the requirements of the JavaScript specification's Script or Module
productions, for classic scripts and JavaScript module scripts respectively. [JAVASCRIPT]

The contents of the external script resource for CSS module scripts must conform to the requirements of the CSS specification. [CSS]

The contents of the external script resource for JSON module scripts must conform to the requirements of the JSON specification [JSON].

When used to include data blocks, the data must be embedded inline, the format of the data must be given using the type attribute, and the contents of the script
element must conform to the requirements defined for the format used. The src, async, nomodule, defer, crossorigin, integrity, and referrerpolicy
attributes must not be specified.

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 ✔ MDN
(and will be ignored if it is).

The async and defer attributes are boolean attributes that indicate how the script should be evaluated. Classic scripts may specify defer or async, but must not
specify either unless the src attribute is present. Module scripts may specify the async attribute, but must not specify the defer attribute.

There are several possible modes that can be selected using these attributes, and depending on the script's type.

For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available (potentially
before parsing completes). If the async attribute is not present but the defer attribute is present, then the classic script will be fetched in parallel and evaluated
when the page has finished parsing. If neither attribute is present, then the script is fetched and evaluated immediately, blocking parsing until these are both
complete.

For module scripts, if the async attribute is present, then the module script and all its dependencies will be fetched in parallel to parsing, and the module script will
be evaluated as soon as it is available (potentially before parsing completes). Otherwise, the module script and its dependencies will be fetched in parallel to parsing
and evaluated when the page has finished parsing. (The defer attribute has no effect on module scripts.)

This is all summarized in the following schematic diagram:


Scripting:
<script>
HTML Parser:
Scripting:
<script defer>
HTML Parser:
Scripting:
<script async>
HTML Parser:
Scripting:
<script type="module">
HTML Parser:
Scripting:
<script type="module" async>
HTML Parser:
parser fetch execution runtime →

Note
The exact processing details for these attributes are, for mostly historical reasons, somewhat non-trivial, involving a number of aspects of HTML. The
implementation requirements are therefore by necessity scattered throughout the specification. The algorithms below (in this section) describe the core of this
processing, but these algorithms reference and are referenced by the parsing rules for script start and end tags in HTML, in foreign content, and in XML, the
rules for the [Link]() method, the handling of scripting, etc.

The defer attribute may be specified even if the async attribute is specified, to cause legacy web browsers that only support defer (and not async) to fall back to
the defer behavior instead of the blocking behavior that is the default.

The crossorigin attribute is a CORS settings attribute. For classic scripts, it controls whether error information will be exposed, when the script is obtained from
other origins. For module scripts, it controls the credentials mode used for cross-origin requests.

Note
Unlike classic scripts, module scripts require the use of the CORS protocol for cross-origin fetching.

The integrity attribute represents the integrity metadata for requests which this element is responsible for. The value is text. The integrity attribute must not be
specified when the src attribute is not specified. [SRI]

The referrerpolicy attribute is a referrer policy attribute. Its purpose is to set the referrer policy used when fetching the script, as well as any scripts imported
from it. [REFERRERPOLICY]

Example
An example of a script element's referrer policy being used when fetching imported scripts but not other subresources:

<script referrerpolicy="origin">
fetch('/api/data'); // not fetched with <script>'s referrer policy
import('./[Link]'); // is fetched with <script>'s referrer policy ("origin" in this case)
</script>

Changing the src, type, nomodule, async, defer, crossorigin, integrity, and referrerpolicy attributes dynamically has no direct effect; these attributes
are only used at specific times described below.
✔ MDN
The IDL attributes src, type, defer, and integrity, must each reflect the respective content attributes of the same name.

The referrerPolicy IDL attribute must reflect the referrerpolicy content attribute, limited to only known values.

The crossOrigin IDL attribute must reflect the crossorigin content attribute, limited to only known values.

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.

For web developers (non-normative)


[Link] [ = value ]
Returns the child text content of the element.
Can be set, to replace the element's children with the given value.

[Link](type)
Returns true if the given type is a script type supported by the user agent. The possible script types in this specification are "classic" and "module",
but others might be added in the future.

The text attribute's getter must return this script element's child text content.

The text attribute's setter must string replace all with the given value within this script element.

Note
When inserted using the [Link]() method, script elements usually execute (typically blocking further script execution or HTML parsing). When
inserted using the innerHTML and outerHTML attributes, they do not execute at all. ⚠ MDN
The supports(type) method steps are:

1. If type is "classic", then return true.

2. If type is "module", then return true.

3. Return false.

Note
The type argument has to exactly match these values; we do not perform an ASCII case-insensitive match. This is different from how type content attribute
values are treated, and how DOMTokenList's supports() method works, but it aligns with the WorkerType enumeration used in the Worker() constructor.

Example
In this example, two script elements are used. One embeds an external classic script, and the other includes some data as a data block.

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

The data in this case might be used by the script to generate the map of a video game. The data doesn't have to be used that way, though; maybe the map data
is actually embedded in other parts of the page's markup, and the data block here is just used by the site's search engine to help users who are looking for
particular features in their game maps.

Example
The following sample shows how a script element can be used to define a function that is then used by other parts of the document, as part of a classic script.
It also shows how a script element can be used to invoke script while the document is being parsed, in this case to initialize the form's output.

<script>
function calculate(form) {
var price = 52000;
if ([Link])
price += 1000;
if ([Link])
price += 2500;
if ([Link])
price += 5000;
if ([Link])
price += 250;
[Link] = 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([Link]);
</script>
</form>

Example
The following sample shows how a script element can be used to include an external JavaScript module script.

<script type="module" src="[Link]"></script>

This module, and all its dependencies (expressed through JavaScript import statements in the source file), will be fetched. Once the entire resulting module
graph has been imported, and the document has finished parsing, the contents of [Link] will be evaluated.

Additionally, if code from another script element in the same Window imports the module from [Link] (e.g. via import "./[Link]";), then the same
JavaScript module script created by the former script element will be imported.
Example
This example shows how to include a JavaScript module script for modern user agents, and a classic script for older user agents:

<script type="module" src="[Link]"></script>


<script nomodule defer src="[Link]"></script>

In modern user agents that support JavaScript 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 JavaScript 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.

Example
The following sample shows how a script element can be used to write an inline JavaScript module script that performs a number of substitutions on the
document's text, in order to make for a more interesting reading experience (e.g. on a news site): [XKCD1288]

<script type="module">
import { walkAllTextNodeDescendants } from "./[Link]";

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 [Link]()) {
[Link] = [Link](new RegExp(`\\b${before}\\b`, "ig"), after);
}
}

walkAllTextNodeDescendants([Link], substitute);
</script>

Some notable features gained by using a JavaScript module script include the ability to import functions from other JavaScript modules, strict mode by default,
and how top-level declarations do not introduce new properties onto the global object. Also note that no matter where this script element appears in the
document, it will not be evaluated until both document parsing has complete and its dependency ([Link]) has been fetched and evaluated.

Example
The following sample shows how a JSON module script can be imported from inside a JavaScript module script:

<script type="module">
import peopleInSpace from "[Link] assert { type: "json" };

const list = [Link]("#people-in-space");


for (const { craft, name } of [Link]) {
const li = [Link]("li");
[Link] = `${name} / ${craft}`;
[Link](li);
}
</script>

MIME type checking for module scripts is strict. In order for the fetch of the JSON module script to succeed, the HTTP reponse must have a JSON MIME type,
for example Content-Type: text/json. On the other hand, if the assert { type: "json" } part of the statement is omitted, it is assumed that the
intent is to import a JavaScript module script, and the fetch will fail if the HTTP response has a MIME type that is not a JavaScript MIME type.

§ [Link] Processing model

A script element has several associated pieces of state.

A script element has a flag indicating whether or not it 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.

A script element has a parser document, which is either null or a Document. Initially, its value must be null. It is set by the HTML parser and the XML parser on
script elements they insert, and affects the processing of those elements. script elements with non-null parser documents are known as "parser-inserted".
A script element has 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.

A script element has 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 script's type for a script element is either "classic" or "module". It is determined when the script is prepared, based on the type attribute of the element at
that time.

A script element has a preparation-time document, which is a Document determined near the beginning of the prepare a script algorithm. It is used to prevent
scripts that move between documents during preparation from executing.

A script element has 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.

The script's script for a script element is either null or a script resulting from preparing the element. This is set asynchronously after the classic script or module
graph 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 "parser-inserted" experiences one of the events listed in the following list, the user agent must immediately prepare the script
element:

The script element becomes connected.

The script element is connected and a node or document fragment is inserted into the script element, after any script elements inserted at that time.

The script element is connected and has a src attribute set where previously the element had no such attribute.

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

1. If the script element is marked as having "already started", then return. The script is not executed.

2. Let parser document be the element's parser document.

3. Set the element's parser document to null.

Note
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.

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

Note
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.

5. Let source text be the element's child text content.

6. If the element has no src attribute, and source text is the empty string, then return. The script is not executed.

7. If the element is not connected, then return. The script is not executed.

8. If either:

the script element has a type attribute and its value is the empty string, or
the script element has no type attribute but it has a language attribute and that attribute's value is the empty string, or
the script element has neither a type attribute nor a language attribute, then

...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.

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.

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

Determine the script's type as follows:

If the script block's type string with leading and trailing ASCII whitespace stripped is a JavaScript MIME type essence match, the script's type is
"classic".

If the script block's type string is an ASCII case-insensitive match for the string "module", the script's type is "module".

If neither of the above conditions are true, then return. No script is executed.

9. If parser document is non-null, then set the element's parser document back to parser document and set the element's "non-blocking" flag to false.

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

11. Set the element's preparation-time document to its node document.


12. If parser document is non-null, and parser document is not equal to the element's preparation-time document, then return.

13. If scripting is disabled for the script element, then return. The script is not executed.

Note
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]

14. If the script element has a nomodule content attribute and the script's type is "classic", then return. The script is not executed.

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

15. 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 source text, then return. The script is not executed. [CSP]

16. 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 return. 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 return. The script is not executed.

17. 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.

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

18. Let classic script CORS setting be the current state of the element's crossorigin content attribute.

19. Let module script credentials mode be the CORS settings attribute credentials mode for the element's crossorigin content attribute.

20. Let cryptographic nonce be the element's [[CryptographicNonce]] internal slot's value.

21. 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.

22. Let referrer policy be the current state of the element's referrerpolicy content attribute.

23. Let parser metadata be "parser-inserted" if the script element is "parser-inserted", and "not-parser-inserted" otherwise.

24. Let options be a script fetch options whose cryptographic nonce is cryptographic nonce, integrity metadata is integrity metadata, parser metadata is parser
metadata, credentials mode is module script credentials mode, and referrer policy is referrer policy.

25. Let settings object be the element's node document's relevant settings object.

26. 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 return.

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 return. Otherwise, let url be the resulting URL record.

6. Switch on the script's type:

↪ "classic"
Fetch a classic script given url, settings object, options, classic script CORS setting, and encoding.

↪ "module"
Fetch an external module script graph given url, settings object, and options.

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 graph (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.

27. If the element does not have a src content attribute, run these substeps:
1. Let base URL be the script element's node document's document base URL.

2. Switch on the script's type:

↪ "classic"

1. Let script be the result of creating a classic script using source text, settings object, base URL, and options.

2. Set the script's script to script.

3. The script is ready.

↪ "module"

1. Fetch an inline module script graph, given source text, base URL, settings object, and options. When this asynchronously
completes, set the script's script to the result. At that time, the script is ready.

28. 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 is "parser-
inserted", and the element does not have an async attribute
↪ If the script's type is "module", and the element is "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 is "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 element's preparation-time
document.

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 return 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 element's preparation-time document.

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 is "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 element's parser document has a style sheet that is
blocking scripts
The element is the pending parsing-blocking script of its parser document. (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.

↪ Otherwise
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).

Note
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
the original Document has a style sheet that is blocking scripts when it was parsed, but then the script is moved to another Document before the blocking style
sheet(s) loaded, the script still blocks the parser until the style sheets are all loaded, at which time the script executes and the parser is unblocked).

To execute a script block given a script element scriptElement:

1. Let document be scriptElement's node document.

2. If scriptElement's preparation-time document is not equal to document, then return.


3. If the script's script is null for scriptElement, then fire an event named error at scriptElement, and return.

4. If scriptElement is from an external file, or the script's type for scriptElement is "module", then increment document's ignore-destructive-writes counter.

5. Switch on the script's type for scriptElement:

↪ "classic"

1. Let oldCurrentScript be the value to which document's currentScript object was most recently set.

2. If scriptElement's root is not a shadow root, then set document's currentScript attribute to scriptElement. Otherwise, set it to null.

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

3. Run the classic script given by the script's script for scriptElement.

4. Set document's currentScript attribute to oldCurrentScript.

↪ "module"

1. Assert: document's currentScript attribute is null.

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

6. Decrement the ignore-destructive-writes counter of document, if it was incremented in the earlier step.

7. If scriptElement is from an external file, then fire an event named load at scriptElement.

§ [Link] Scripting languages

User agents are not required to support JavaScript. This standard needs to be updated if a language other than JavaScript comes along and gets similar wide
adoption by web browsers. Until such a time, implementing other languages is in conflict with this standard, given the processing model defined for the script
element.

Servers should use text/javascript for JavaScript resources. Servers should not use other JavaScript MIME types for JavaScript resources, and must not use
non-JavaScript MIME types.

For external JavaScript resources, MIME type parameters in `Content-Type` headers are generally ignored. (In some cases the `charset` parameter has an effect.)
However, for the script element's type attribute they are significant; it uses the JavaScript MIME type essence match concept.

Note
For example, scripts with their type attribute set to "text/javascript; charset=utf-8" will not be evaluated, even though that is a valid JavaScript MIME
type when parsed.

Furthermore, again for external JavaScript resources, special considerations apply around `Content-Type` header processing as detailed in the prepare a script
algorithm and Fetch. [FETCH]

§ [Link] Restrictions for contents of script elements

Note
The easiest and safest way to avoid the rather strange restrictions described in this section is to always escape an ASCII case-insensitive match for "<!--" as
"\x3C!--", "<script" as "\x3Cscript", and "</script" as "\x3C/script" when these sequences appear in literals in scripts (e.g. in strings, regular
expressions, or comments), and to avoid writing code that uses such constructs in expressions. Doing so avoids the pitfalls that the restrictions in this section are
prone to triggering: namely, that, for historical reasons, parsing of script blocks in HTML is a strange and exotic practice that acts unintuitively in the face of
these sequences.

The script element's descendant text content must match the script production in the following ABNF, the character set for which is Unicode. [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 (>)

When a script element contains script documentation, there are further restrictions on the contents of the element, as described in the section below.

Example
The following script illustrates this issue. Suppose you have a script that contains a string, as in:

const example = 'Consider this string: <!-- <script>';


[Link](example);

If one were to put this string directly in a script block, it would violate the restrictions above:

<script>
const example = 'Consider this string: <!-- <script>';
[Link](example);
</script>

The bigger problem, though, and the reason why it would violate those restrictions, is that actually the script would get parsed weirdly: the script block above is
not terminated. That is, what looks like a "</script>" end tag in this snippet is actually still part of the script block. The script doesn't execute (since it's not
terminated); if it somehow were to execute, as it might if the markup looked as follows, it would fail because the script (highlighted here) is not valid JavaScript:

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

What is going on here is that for legacy reasons, "<!--" and "<script" strings in script elements in HTML need to be balanced in order for the parser to
consider closing the block.

By escaping the problematic strings as mentioned at the top of this section, the problem is avoided entirely:

<script>
// Note: `\x3C` is an escape sequence for `<`.
const example = 'Consider this string: \x3C!-- \x3Cscript>';
[Link](example);
</script>
<!-- this is just a comment between script blocks -->
<script>
... // this is a new script block
</script>

It is possible for these sequences to naturally occur in script expressions, as in the following examples:

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

In such cases the characters cannot be escaped, but the expressions can be rewritten so that the sequences don't occur, as in:

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


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

Doing this also avoids a different pitfall as well: for related historical reasons, the string "<!--" in classic scripts is actually treated as a line comment start, just like
"//".
§ [Link] Inline documentation for external scripts

If a script element's src attribute is specified, then the contents of the script element, if any, must be such that the value of the text IDL attribute, which is
derived from the element's contents, matches the documentation production in the following ABNF, the character set for which is Unicode. [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 (/)

Note
This corresponds to putting the contents of the element in JavaScript comments.

Note
This requirement is in addition to the earlier restrictions on the syntax of contents of script elements.

Example
This allows authors to include documentation, such as license information or API information, inside their documents while still referring to external script files.
The syntax is constrained so that authors don't accidentally include what looks like valid script while also providing a src attribute.

<script src="[Link]">
// create new instances using:
// var e = new Effect();
// start the effect using .play, stop using .stop:
// [Link]();
// [Link]();
</script>

§ [Link] Interaction of script elements and XSLT

This section is non-normative.

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 implementers, based on existing implementations:

When an XSLT transformation program is triggered by an <?xml-stylesheet?> processing instruction and the browser implements a direct-to-DOM
transformation, script elements created by the XSLT processor need to have its parser document set correctly, and run in document order (modulo scripts
marked defer or async), immediately, as the transformation is occurring.

The XSLTProcessor transformToDocument() method adds elements to a Document object with a null browsing context, and, accordingly, any script
elements they create need to have their "already started" flag set in the prepare a script algorithm and never get executed (scripting is disabled). Such
script elements still need to have their parser document set, though, such that their async IDL attribute will return false in the absence of an async
content attribute.

The XSLTProcessor transformToFragment() method needs to create a fragment that is equivalent to one built manually by creating the elements using
[Link](). For instance, it needs to create script elements with null parser document and that don't have their "already started"
flag set, so that they will execute when the fragment is inserted into a document.

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.

✔ MDN
§ 4.12.2 The noscript element

Categories:
Metadata content.
Flow content.
Phrasing content.

Contexts in which this element can be used:


In a head element of an HTML document, if there are no ancestor noscript elements.
Where phrasing content is expected in HTML documents, if there are no ancestor noscript elements.

Content model:
When scripting is disabled, in a head element: in any order, zero or more link elements, zero or more style elements, and zero or more meta
elements.
When scripting is disabled, not in a head element: transparent, but there must be no noscript element descendants.
Otherwise: text that conforms to the requirements given in the prose.

Tag omission in text/html:


Neither tag is omissible.

Content attributes:
Global attributes

Accessibility considerations:
For authors.
For implementers.

DOM interface:
Uses HTMLElement.

The noscript element represents nothing if scripting is enabled, and represents its children if scripting is disabled. It is used to present different markup to user
agents that support scripting and those that don't support scripting, by affecting how the document is parsed.

When used in HTML documents, the allowed content model is as follows:

In a head element, if scripting is disabled for the noscript element


The noscript element must contain only link, style, and meta elements.

In a head element, if scripting is enabled for the noscript element


The noscript element must contain only text, except that invoking the HTML fragment parsing algorithm with the noscript element as the context
element and the text contents as the input must result in a list of nodes that consists only of link, style, and meta elements that would be conforming if
they were children of the noscript element, and no parse errors.

Outside of head elements, if scripting is disabled for the noscript element


The noscript element's content model is transparent, with the additional restriction that a noscript element must not have a noscript element as an
ancestor (that is, noscript can't be nested).

Outside of head elements, if scripting is enabled for the noscript element


The noscript element must contain only text, except that the text must be such that running the following algorithm results in a conforming document with
no noscript elements and no script elements, and such that no step in the algorithm throws an exception or causes an HTML parser to flag a parse error:

1. Remove every script element from the document.

2. Make a list of every noscript element in the document. For every noscript element in that list, perform the following steps:

1. Let s be the child text content of the noscript element.

2. Set the outerHTML attribute of the noscript element to the value of s. (This, as a side-effect, causes the noscript element to be
removed from the document.) [DOMPARSING]

Note
All these contortions are required because, for historical reasons, the noscript element is handled differently by the HTML parser based on whether scripting
was enabled or not when the parser was invoked.

The noscript element must not be used in XML documents.

Note
The noscript element is only effective in the HTML syntax, it has no effect in the XML syntax. This is because the way it works is by essentially "turning off" the
parser when scripts are enabled, so that the contents of the element are treated as pure text and not as real elements. XML does not define a mechanism by
which to do this.

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.

Example
In the following example, a noscript element is used to provide fallback for a script.

<form action="[Link]">
<p>
<label for=x>Number</label>:
<input id="x" name="x" type="number">
</p>
<script>
var x = [Link]('x');
var output = [Link]('p');
[Link] = 'Type a number; it will be squared right then!';
[Link](output);
[Link] = function () { return false; }
[Link] = function () {
var v = [Link];
[Link] = v + ' squared is ' + v * v;
};
</script>
<noscript>
<input type=submit value="Calculate Square">
</noscript>
</form>

When script is disabled, a button appears to do the calculation on the server side. When script is enabled, the value is computed on-the-fly instead.

The noscript element is a blunt instrument. Sometimes, scripts might be enabled, but for some reason the page's script might fail. For this reason, it's
generally better to avoid using noscript, and to instead design the script to change the page from being a scriptless page to a scripted page on the fly, as in
the next example:

<form action="[Link]">
<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 = [Link]('x');
var output = [Link]('p');
[Link] = 'Type a number; it will be squared right then!';
[Link](output);
[Link] = function () { return false; }
[Link] = function () {
var v = [Link];
[Link] = v + ' squared is ' + v * v;
};
var submit = [Link]('submit');
[Link](submit);
</script>
</form>

The above technique is also useful in XML documents, since noscript is not allowed there.

✔ MDN
§ 4.12.3 The template element

Categories:
✔ MDN
Metadata content.
Flow content.
Phrasing content.
Script-supporting element.

Contexts in which this element can be used:


Where metadata content is expected.
Where phrasing content is expected.
Where script-supporting elements are expected.
As a child of a colgroup element that doesn't have a span attribute.

Content model:
Nothing (for clarification, see example).

Tag omission in text/html:


Neither tag is omissible.

Content attributes:
Global attributes

Accessibility considerations:
For authors.
For implementers.

DOM interface:
IDL [Exposed=Window]
interface HTMLTemplateElement : HTMLElement {
[HTMLConstructor] constructor();

readonly attribute DocumentFragment content;


};

The template element is used to declare fragments of HTML that can be cloned and inserted in the document by script.

In a rendering, the template element represents nothing.

The template contents of a template element are not children of the element itself.
Note
It is also possible, as a result of DOM manipulation, for a template element to contain Text nodes and element nodes; however, having any is a violation of the
template element's content model, since its content model is defined as nothing.

Example
For example, consider the following document:

<!doctype html>
<html lang="en">
<head>
<title>Homework</title>
<body>
<template id="template"><p>Smile!</p></template>
<script>
let num = 3;
const fragment = [Link]('template').[Link](true);
while (num-- > 1) {
[Link]([Link](true));
[Link] += [Link];
}
[Link](fragment);
</script>
</html>

The p element in the template is not a child of the template in the DOM; it is a child of the DocumentFragment returned by the template element's
content IDL attribute.

If the script were to call appendChild() on the template element, that would add a child to the template element (as for any other element); however, doing
so is a violation of the template element's content model.

For web developers (non-normative)


[Link]
Returns the template contents (a DocumentFragment).

Each template element has an associated DocumentFragment object that is its template contents. The template contents have no conformance requirements.
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 (whose browsing context is null). 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.

Note
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.

Note
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, return.

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.

Example
In this example, a script populates a table four-column with data from a data structure, using a template to provide the element structure instead of manually
generating the structure from markup.

<!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 = [Link]('#row');
for (var i = 0; i < [Link]; i += 1) {
var cat = data[i];
var clone = [Link](true);
var cells = [Link]('td');
cells[0].textContent = [Link];
cells[1].textContent = [Link];
cells[2].textContent = [Link];
cells[3].textContent = [Link];
[Link](clone);
}
</script>

This example uses cloneNode() on the template's contents; it could equivalently have used [Link](), which does the same thing. The
only difference between these two APIs is when the node document is updated: with cloneNode() it is updated when the nodes are appended with
appendChild(), with [Link]() it is updated when the nodes are cloned.

§ [Link] Interaction of template elements with XSLT and XPath

This section is non-normative.

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 implementers, which are intended to be consistent with other processing described in this specification:

An XSLT processor based on an XML parser that acts as described in this specification needs to act as if template elements contain as descendants their
template contents for the purposes of the transform.

An XSLT processor that outputs a DOM needs to ensure that nodes that would go into a template element are instead placed into the element's template
contents.

XPath evaluation using the XPath DOM API when applied to a Document parsed using the HTML parser or the XML parser described in this specification
needs to ignore template contents.

✔ MDN
§ 4.12.4 The slot element

Categories:
✔ MDN
Flow content.
Phrasing content.

Contexts in which this element can be used:


Where phrasing content is expected.

Content model:
Transparent

Tag omission in text/html:


Neither tag is omissible.

Content attributes:
Global attributes
name — Name of shadow tree slot

Accessibility considerations:
For authors.
For implementers.

DOM interface:
IDL [Exposed=Window]
interface HTMLSlotElement : HTMLElement {
[HTMLConstructor] constructor();

[CEReactions] attribute DOMString name;


sequence<Node> assignedNodes(optional AssignedNodesOptions options = {});
sequence<Element> assignedElements(optional AssignedNodesOptions options = {});
undefined assign((Element or Text)... nodes);
};

dictionary AssignedNodesOptions {
boolean flatten = false;
};

The slot element defines a slot. It is typically used in a shadow tree. A slot element represents its assigned nodes, if any, and its contents otherwise.

The name content attribute may contain any string value. It represents a slot's name.

Note
The name attribute is used to assign slots to other elements: a slot element with a name attribute creates a named slot to which any element is assigned if that
element has a slot attribute whose value matches that name attribute's value, and the slot element is a child of the shadow tree whose root's host has that
corresponding slot attribute value.

For web developers (non-normative)


[Link]
Can be used to get and set slot's name.

[Link]()
Returns slot's assigned nodes.

[Link]({ flatten: true })


Returns slot's assigned nodes, if any, and slot's children otherwise, and does the same for any slot elements encountered therein, recursively, until
there are no slot elements left.

[Link]()
Returns slot's assigned nodes, limited to elements.

[Link]({ flatten: true })


Returns the same as assignedNodes({ flatten: true }), limited to elements.

[Link](...nodes)
Sets slot's manually assigned nodes to the given nodes.

The name IDL attribute must reflect the content attribute of the same name.

The slot element has manually assigned nodes, which is an ordered set of slottables set by assign(). This set is initially empty.

Note
The manually assigned nodes set can be implemented using weak references to the slottables, because this set is not directly accessible from script.

The assignedNodes(options) method steps are:

1. If options["flatten"] is false, then return this's assigned nodes.

2. Return the result of finding flattened slottables with this.

The assignedElements(options) method steps are:

1. If options["flatten"] is false, then return this's assigned nodes, filtered to contain only Element nodes.

2. Return the result of finding flattened slottables with this, filtered to contain only Element nodes.

The assign(...nodes) method steps are: MDN

1. For each node of this's manually assigned nodes, set node's manual slot assignment to null.

2. Let nodesSet be a new ordered set.


3. For each node of nodes:

1. If node's manual slot assignment refers to a slot, then remove node from that slot's manually assigned nodes.

2. Set node's manual slot assignment to this.

3. Append node to nodesSet.

4. Set this's manually assigned nodes to nodesSet.

5. Run assign slottables for a tree for this's root.

← 4.11 Interactive elements — Table of Contents — 4.12.5 The canvas element →


File an issue about the selected text

Common questions

Powered by AI

Cloned script elements retain certain state characteristics from their original elements. This includes the "already started" flag, which is copied if set during cloning, indicating the script should not restart if moved or re-used—an important consistency measure . Additionally, cloned scripts maintain their type and defer settings, ensuring they behave as expected in the new context. To ensure consistency, the cloning process must also reset or update context-specific states like the "parser document" for parser-inserted scripts, ensuring they associate correctly with new DOM trees and environments .

Inline scripts are executed at the point they appear in the document and are often used for instructions that need immediate execution. In contrast, external script resources, defined with the 'src' attribute, involve downloading the script before execution, which can introduce delays. However, complex dependency management is more manageable with external scripts as they can be properly ordered and fetched asynchronously or deferred using the 'async' and 'defer' attributes . In the case of module scripts, inline content isn't executed until dependencies (such as other modules specified in an import statement) are fully fetched and evaluated, ensuring dependencies are resolved before execution .

Using 'async' and 'defer' attributes with script elements introduces challenges related to script execution order. 'Async' causes the script to be executed as soon as it's available, potentially causing race conditions if the script relies on DOM elements that aren't fully loaded. 'Defer' ensures the script executes after the HTML parsing is complete, maintaining order but potentially delaying execution. Developers should carefully plan scripts' dependencies; using 'defer' helps keep critical scripts ordered and ensures dependent scripts aren't executed prematurely. Combining attribute use with module scripts and thoughtful organization of page load scripts can help optimize performance and reliability .

JavaScript module scripts offer several advantages over classic scripts for modern web development. They allow importing functions and variables from other modules, supporting more organized and modular code development. Module scripts operate in strict mode by default, promoting better coding practices by catching common errors. Additionally, top-level declarations in module scripts do not leak to the global space, minimizing potential conflicts in the global namespace. This approach helps maintain code integrity and reduces unintended side effects, enabling cleaner and more maintainable codebases .

The HTML template element allows developers to define a piece of HTML that is not rendered by default, making it an ideal tool for creating reusable components. The element's contents are contained in a DocumentFragment object, enabling them to be cloned and inserted into the document dynamically using scripts. This mechanism aligns with the separation of HTML structure from JavaScript functionality, aiding in clearer and more maintainable code. However, limitations include the requirement that template contents are inert—they can't contain scripts or live data by themselves. The content cannot interact with the DOM until explicitly inserted with JavaScript, which adds complexity when integrating dynamic user interactions .

The 'noscript' tag provides a fallback mechanism, allowing browsers with disabled scripting capabilities to present alternative content. For example, it can display a message or functionality that compensates for the disabled script, such as server-side processing options. However, it is often viewed as less favorable in modern development because it strictly requires scripts to be entirely disabled for the tag's content to appear. This is limiting, as it does not account for partial scripting failures or includes scenarios where scripts fail to execute for other reasons. Moreover, the approach is considered blunt because it requires duplication of functionality in both script and non-script forms, complicating maintenance .

A DocumentFragment is used to hold the contents of a template element, keeping them inert—meaning they don't impact the document's live DOM. This allows developers to define complex HTML structures or reusable components without them being active scripts or part of the rendering flow until they are explicitly cloned and inserted into the document by a script. This encapsulation within a DocumentFragment ensures that the template's content remains inactive until intentionally utilized, helping accomplish deferred rendering and avoiding unnecessary loading of resources or execution before needed .

The 'type' attribute in an HTML script element specifies the type of script being used and can affect its execution. For classic scripts, omitting the attribute or setting it to specific JavaScript MIME types means the script is a classic script, which can be affected by the 'async' and 'defer' attributes when the 'src' attribute is used. 'Module' scripts, on the other hand, are unaffected by the 'defer' attribute but can be affected by 'async,' regardless of the 'src' attribute state . If the 'type' is set to anything other than JavaScript MIME types, the script is treated as a data block and is not executed .

Strict MIME type checking for module scripts implies that only scripts with correct MIME types are executed. For example, a JSON module script must have a 'Content-Type' of 'application/json' or 'text/json'. This prevents executing scripts that do not match expectations, enhancing security by avoiding execution of potentially harmful or incorrect content types. The use of assertions (e.g., 'assert { type: "json" }') further enforces expected content types, causing fetch failures if the server response doesn't match, holding developers accountable for correct server configurations and response headers .

The 'nomodule' attribute, when used in conjunction with script tags, prevents the script from being executed in user agents that support module scripts. This is intended to provide compatibility by allowing module scripts to run in modern browsers, while classic scripts are executed in older browsers. If a browser doesn't recognize 'module' scripts, the script tagged with 'nomodule' will run, providing a fallback . By ignoring scripts marked with 'nomodule' in modern browsers, developers can ensure that their code doesn't run twice or produce errors .

You might also like