This is a work in progress! For the latest updates from the HTML WG, possibly including important bug fixes, please look at the editor's draft instead. There may also be a more up-to-date Working Draft with changes based on resolution of Last Call issues.
4.3 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.
For example, instead of using 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.
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.
4.3.1 The script element
- Categories
- Metadata content.
- Flow content.
- Phrasing content.
- Contexts in which this element can be used:
- Where metadata content is expected.
- Where phrasing content is expected.
- Content model:
- If there is no
srcattribute, depends on the value of thetypeattribute, but must match script content restrictions. - If there is a
srcattribute, the element must be either empty or contain only script documentation that also matches script content restrictions. - Content attributes:
- Global attributes
srcasyncdefertypecharset- DOM interface:
-
interface HTMLScriptElement : HTMLElement { attribute DOMString src; attribute boolean async; attribute boolean defer; attribute DOMString type; attribute DOMString charset; attribute DOMString text; };
The script element allows authors to include dynamic
script and data blocks in their documents. The element does not
represent content for the user.
When used to include dynamic scripts, the scripts may either be
embedded inline or may be imported from an external file using the
src attribute. If the language
is not that described by "text/javascript",
then the type attribute must
be present, as described below. Whatever language is used, the
contents of the script element must conform with the
requirements of that language's specification.
When used to include data blocks (as opposed to scripts), the
data must be embedded inline, the format of the data must be given
using the type attribute, the
src attribute must not be
specified, and the contents of the script element must
conform to the requirements defined for the format used.
The type
attribute gives the language of the script or format of the data. If
the attribute is present, its value must be a valid MIME
type. The charset parameter must not be
specified. The default, which is used if the attribute is absent,
is "text/javascript".
The src
attribute, if specified, gives the address of the external script
resource to use. The value of the attribute must be a valid
non-empty URL potentially surrounded by spaces identifying a
script resource of the type given by the type attribute, if the attribute is
present, or of the type "text/javascript", if
the attribute is absent. A resource is a script resource of a given
type if that type identifies a scripting language and the resource
conforms with the requirements of that language's specification.
The charset
attribute gives the character encoding of the external script
resource. The attribute must not be specified if the src attribute is not present. If the
attribute is set, its value must be a valid character encoding name,
must be an ASCII case-insensitive match for the
preferred MIME name for that encoding, and must match
the encoding given in the charset parameter of
the Content-Type metadata of the
external file, if any. [IANACHARSET]
The async and
defer attributes
are boolean attributes that
indicate how the script should be executed. The defer and async attributes must not be
specified if the src attribute
is not present.
There are three possible modes that can be selected using these
attributes. If the async
attribute is present, then the script will be executed
asynchronously, as soon as it is available. If the async attribute is not present but
the defer attribute is
present, then the script is executed when the page has finished
parsing. If neither attribute is present, then the script is
fetched and executed immediately, before the user agent continues
parsing the page.
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 document.write() 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
synchronous blocking behavior that is the default.
Changing the src, type, charset, async, and defer attributes dynamically has no
direct effect; these attribute are only used at specific times
described below.
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"). When a
script element is cloned, the "already started" flag, if
set, must be propagated to the clone when it is created.
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
"force-async" . 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
"force-async" flag is set has a async content attribute added, the
element's "force-async" 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 last few pieces of state are the script block's
type , the script block's character
encoding , and the script block's fallback
character encoding . They are determined when the script
is prepared, based on the attributes on the element at that time,
and the Document of the script
element.
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 synchronously prepare the script
element:
- The
scriptelement gets inserted into a document. - The
scriptelement is in aDocumentand its child nodes are changed. - The
scriptelement is in aDocumentand has asrcattribute set where previously the element had no such attribute.
To prepare a script , the user agent must act as follows:
-
If the
scriptelement is marked as having "already started", then the user agent must abort these steps at this point. The script is not executed. -
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
scriptelements 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. -
If was-parser-inserted is true and the element does not have an
asyncattribute, then set the element's "force-async" flag to true.This is done so that if a parser-inserted
scriptelement fails to run when the parser tries to run it, but it is later executed after a script dynamically updates it, it will execute asynchronously even if theasyncattribute isn't set. -
If the element has no
srcattribute, and its child nodes, if any, consist only of comment nodes and empty text nodes, then the user agent must abort these steps at this point. The script is not executed. -
If the element is not in a
Document, then the user agent must abort these steps at this point. The script is not executed. -
If either:
- the
scriptelement has atypeattribute and its value is the empty string, or - the
scriptelement has notypeattribute but it has alanguageattribute and that attribute's value is the empty string, or - the
scriptelement has neither atypeattribute nor alanguageattribute, then
...let the script block's type for this
scriptelement be "text/javascript".Otherwise, if the
scriptelement has atypeattribute, let the script block's type for thisscriptelement be the value of that attribute with any leading or trailing sequences of space characters removed.Otherwise, the element has a non-empty
languageattribute; let the script block's type for thisscriptelement be the concatenation of the string "text/" followed by the value of thelanguageattribute.The
languageattribute is never conforming, and is always ignored if there is atypeattribute present. - the
-
If the user agent does not support the scripting language given by the script block's type for this
scriptelement, then the user agent must abort these steps at this point. The script is not executed. -
If was-parser-inserted is true, then flag the element as "parser-inserted" again, and set the element's "force-async" flag to false.
-
The user agent must set the element's "already started" flag.
The state of the element at this moment is later used to determine the script source.
-
If the element is flagged as "parser-inserted", but the element's
Documentis not theDocumentof the parser that created the element, then abort these steps. -
If scripting is disabled for the
scriptelement, then the user agent must 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'sresponseXMLdocuments, scripts inDOMParser-created documents, scripts in documents created byXSLTProcessor'stransformToDocumentfeature, and scripts that are first inserted by a script into aDocumentthat was created using thecreateDocument()API. [XHR] [DOMPARSER] [DOMCORE] -
If the
scriptelement has aneventattribute and aforattribute, then run these substeps:Let for be the value of the
forattribute.Let event be the value of the
eventattribute.Strip leading and trailing whitespace from event and for.
If for is not an ASCII case-insensitive match for the string "
window", then the user agent must abort these steps at this point. The script is not executed.If event is not an ASCII case-insensitive match for either the string "
onload" or the string "onload()", then the user agent must abort these steps at this point. The script is not executed.
-
If the
scriptelement has acharsetattribute, then let the script block's character encoding for thisscriptelement be the encoding given by thecharsetattribute.Otherwise, let the script block's fallback character encoding for this
scriptelement be the same as the encoding of the document itself.Only one of these two pieces of state is set.
-
If the element has a
srcattribute whose value is not the empty string, then the value of that attribute must be resolved relative to the element, and if that is successful, the specified resource must then be fetched, from the origin of the element'sDocument.If the
srcattribute's value is the empty string or if it could not be resolved, then the user agent must queue a task to fire a simple event namederrorat the element, and abort these steps.For historical reasons, if the URL is a
javascript:URL, then the user agent must not, despite the requirements in the definition of the fetching algorithm, actually execute the script in the URL; instead the user agent must act as if it had received an empty HTTP 400 response.For performance reasons, user agents may start fetching the script as soon as the attribute is set, instead, in the hope that the element will be inserted into the document. Either way, once the element is inserted into the document, the load must have started. If the UA performs such prefetching, but the element is never inserted in the document, or the
srcattribute is dynamically changed, then the user agent will not execute the script, and the fetching process will have been effectively wasted. -
Then, the first of the following options that describes the situation must be followed:
- If the element has a
srcattribute, and the element has adeferattribute, and the element has been flagged as "parser-inserted", and the element does not have anasyncattribute -
The element must be added to the end of the list of scripts that will execute when the document has finished parsing associated with the
Documentof the parser that created the element.The task that the networking task source places on the task queue once the fetching algorithm has completed must set the element's "ready to be parser-executed" flag. The parser will handle executing the script.
- If the element has a
srcattribute, and the element has been flagged as "parser-inserted", and the element does not have anasyncattribute -
The element is the pending parsing-blocking script of the
Documentof the parser that created the element. (There can only be one such script perDocumentat a time.)The task that the networking task source places on the task queue once the fetching algorithm has completed must set the element's "ready to be parser-executed" flag. The parser will handle executing the script.
- If the element does not
have a
srcattribute, and the element has been flagged as "parser-inserted", and theDocumentof the HTML parser or XML parser that created thescriptelement has a style sheet that is blocking scripts -
The element is the pending parsing-blocking script of the
Documentof the parser that created the element. (There can only be one such script perDocumentat a time.)Set the element's "ready to be parser-executed" flag. The parser will handle executing the script.
- If the element has a
srcattribute, does not have anasyncattribute, and does not have the "force-async" flag set -
The element must be added to the end of the list of scripts that will execute in order as soon as possible associated with the
Documentof thescriptelement at the time the prepare a script algorithm started.The task that the networking task source places on the task queue once the fetching algorithm has completed must run the following steps:
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.
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.
Remove the first element from this list of scripts that will execute in order as soon as possible.
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 element has a
srcattribute -
The element must be added to the set of scripts that will execute as soon as possible of the
Documentof thescriptelement at the time the prepare a script algorithm started.The task that the networking task source places on the task queue once the fetching algorithm has completed must execute the script block and then remove the element from the set of scripts that will execute as soon as possible.
- Otherwise
- The user agent must immediately execute the script block, even if other scripts are already executing.
- If the element has a
Fetching an external script must delay the load event of the element's document until the task that is queued by the networking task source once the resource has been fetched (defined above) has been run.
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:
-
If the element is flagged as "parser-inserted", but the element's
Documentis not theDocumentof the parser that created the element, then abort these steps. -
Jump to the appropriate set of steps from the list below:
- If the load resulted in an error (for example a DNS error, or an HTTP 404 error)
Executing the script block must just consist of firing a simple event named
errorat the element.- If the load was successful
-
Executing the script block must consist of running the following steps. For the purposes of these steps, the script is considered to be from an external file if, while the prepare a script algorithm above was running for this script, the
scriptelement had asrcattribute specified.-
Initialize the script block's source as follows:
- If the script is from an external file and the script block's type is a text-based language
-
The contents of that file, interpreted as string of Unicode characters, are the script source.
To obtain the string of Unicode characters, the user agent run the following steps:
If the resource's Content Type metadata, if any, specifies a character encoding, and the user agent supports that encoding, then let character encoding be that encoding, and jump to the bottom step in this series of steps.
If the algorithm above set the script block's character encoding, then let character encoding be that encoding, and jump to the bottom step in this series of steps.
For each of the rows in the following table, starting with the first one and going down, if the file has as many or more bytes available than the number of bytes in the first column, and the first bytes of the file match the bytes given in the first column, then set character encoding to the encoding given in the cell in the second column of that row, and jump to the bottom step in this series of steps:
Bytes in Hexadecimal Encoding FE FF Big-endian UTF-16 FF FE Little-endian UTF-16 EF BB BF UTF-8 This step looks for Unicode Byte Order Marks (BOMs).
Let character encoding be the script block's fallback character encoding.
Convert the file to Unicode using character encoding, following the rules for doing so given by the specification for the script block's type.
- If the script is from an external file and the script block's type is an XML-based language
-
The external file is the script source. When it is later executed, it must be interpreted in a manner consistent with the specification defining the language given by the script block's type.
- If the script is inline and the script block's type is a text-based language
-
The value of the
textIDL attribute at the time the element's "already started" flag was last set is the script source. - If the script is inline and the script block's type is an XML-based language
-
The child nodes of the
scriptelement at the time the element's "already started" flag was last set are the script source.
-
If the script is from an external file, then increment the ignore-destructive-writes counter of the
scriptelement'sDocument. Let neutralized doc be thatDocument. -
Create a script from the
scriptelement node, using the script block's source and the script block's type.This is where the script is compiled and actually executed.
-
Decrement the ignore-destructive-writes counter of neutralized doc, if it was incremented in the earlier step.
-
If the script is from an external file, fire a simple event named
loadat thescriptelement.Otherwise, the script is internal; queue a task to fire a simple event named
loadat thescriptelement.
-
The IDL attributes src , type , charset , and defer , each must
reflect the respective content attributes of the same
name.
The async IDL
attribute controls whether the element will execute asynchronously
or not. If the element's "force-async" flag is set,
then, on getting, the async
IDL attribute must return true, and on setting, the
"force-async" 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 "force-async" flag
is not set, the IDL attribute must reflect the
async content attribute.
- script .
text[ = value ] -
Returns the contents of the element, ignoring child nodes that aren't text nodes.
Can be set, to replace the element's children with the given value.
The IDL attribute text must return a
concatenation of the contents of all the text nodes that are direct children of the
script element (ignoring any other nodes such as
comments or elements), in tree order. On setting, it must act the
same way as the textContent IDL attribute.
When inserted using the document.write() method,
script elements execute (typically synchronously), but
when inserted using innerHTML and outerHTML attributes, they do not
execute at all.
In this example, two script elements are used. One
embeds an external script, and the other includes some data.
<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>
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.
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. 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 (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>
4.3.1.1 Scripting languages
A user agent is said to support the scripting language if the script block's type is an ASCII case-insensitive match for the MIME type string of a scripting language that the user agent implements.
The following lists some MIME type strings and the languages to which they refer:
- "
application/ecmascript" - "
application/javascript" - "
application/x-ecmascript" - "
application/x-javascript" - "
text/ecmascript" - "
text/javascript" - "
text/javascript1.0" - "
text/javascript1.1" - "
text/javascript1.2" - "
text/javascript1.3" - "
text/javascript1.4" - "
text/javascript1.5" - "
text/jscript" - "
text/livescript" - "
text/x-ecmascript" - "
text/x-javascript" - JavaScript. [ECMA262]
- "
text/javascript;e4x=1" - JavaScript with ECMAScript for XML. [ECMA357]
User agents may support other MIME types and other languages.
When examining types to determine if they support the language,
user agents must not ignore unknown MIME parameters — types
with unknown parameters must be assumed to be unsupported. The charset parameter must be treated as an unknown
parameter for the purpose of comparing MIME
types here.
4.3.1.2 Restrictions for contents of script elements
The textContent of a script element
must match the script production in the
following ABNF, the character set for which is Unicode. [ABNF]
script = data1 *( escape [ script-start data3 ] "-->" data1 ) [ escape ] escape = "<!--" data2 *( script-start data3 script-end data2 ) data1 = <any string that doesn't contain a substring that matches not-data1> not-data1 = "<!--" data2 = <any string that doesn't contain a substring that matches not-data2> not-data2 = script-start / "-->" data3 = <any string that doesn't contain a substring that matches not-data3> not-data3 = script-end / "-->" script-start = lt s c r i p t tag-end script-end = lt slash s c r i p t tag-end lt = %x003C ; U+003C LESS-THAN SIGN character (<) slash = %x002F ; U+002F SOLIDUS character (/) 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.
4.3.1.3 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 Unicode character other than U+000A LINE FEED (LF)
not-star = %x0000-0029 / %x002B-10FFFF
; a Unicode character other than U+002A ASTERISK (*)
not-slash = %x0000-002E / %x0030-10FFFF
; a Unicode character other than U+002F SOLIDUS (/)This corresponds to putting the contents of the element in JavaScript comments.
This requirement is in addition to the earlier
restrictions on the syntax of contents of script
elements.
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="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.3.1.4 Interaction of script elements and XSLT
This section is non-normative.
This specification does not define how XSLT interacts with the
script element (or, indeed, how XSLT processing
triggers the stop parsing steps, how it interacts with
the navigation algorithm, or how it
fits in with the event loop). However, in the absence
of another specification actually defining this, here are some
guidelines for implementors, 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,scriptelements created by the XSLT processor need to be marked "parser-inserted" and run in document order (modulo scripts markeddeferorasync), asynchronously while the transformation is occurring.The
XSLTProcessor.transformToDocument()method adds elements to aDocumentthat is not in a browsing context, and, accordingly, anyscriptelements they create need to have their "already started" flag set in the prepare a script algorithm and never get executed (scripting is disabled). Suchscriptelements still need to be marked "parser-inserted", though, such that theirasyncIDL attribute will return false in the absence of anasynccontent attribute.The
XSLTProcessor.transformToFragment()method needs to create a fragment that is equivalent to one built manually by creating the elements usingdocument.createElementNS(). For instance, it needs to createscriptelements that aren't "parser-inserted" 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.
4.3.2 The noscript element
- Categories
- Metadata content.
- Flow content.
- Phrasing content.
- Contexts in which this element can be used:
- In a
headelement of an HTML document, if there are no ancestornoscriptelements. - Where phrasing content is expected in HTML documents, if there are no ancestor
noscriptelements. - Content model:
- When scripting is disabled, in a
headelement: in any order, zero or morelinkelements, zero or morestyleelements, and zero or moremetaelements. - When scripting is disabled, not in a
headelement: transparent, but there must be nonoscriptelement descendants. - Otherwise: text that conforms to the requirements given in the prose.
- Content attributes:
- Global attributes
- 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
headelement, if scripting is disabled for thenoscriptelement The
noscriptelement must contain onlylink,style, andmetaelements.- In a
headelement, if scripting is enabled for thenoscriptelement The
noscriptelement must contain only text, except that invoking the HTML fragment parsing algorithm with thenoscriptelement as the context element and the text contents as the input must result in a list of nodes that consists only oflink,style, andmetaelements that would be conforming if they were children of thenoscriptelement, and no parse errors.- Outside of
headelements, if scripting is disabled for thenoscriptelement The
noscriptelement's content model is transparent, with the additional restriction that anoscriptelement must not have anoscriptelement as an ancestor (that is,noscriptcan't be nested).- Outside of
headelements, if scripting is enabled for thenoscriptelement -
The
noscriptelement must contain only text, except that the text must be such that running the following algorithm results in a conforming document with nonoscriptelements and noscriptelements, and such that no step in the algorithm causes an HTML parser to flag a parse error:- Remove every
scriptelement from the document. - Make a list of every
noscriptelement in the document. For everynoscriptelement in that list, perform the following steps:- Let the parent element be the parent
element of the
noscriptelement. - Take all the children of the parent element
that come before the
noscriptelement, and call these elements the before children. - Take all the children of the parent element
that come after the
noscriptelement, and call these elements the after children. - Let s be the concatenation of all the
text node children of the
noscriptelement. - Set the
innerHTMLattribute of the parent element to the value of s. (This, as a side-effect, causes thenoscriptelement to be removed from the document.) - Insert the before children at the start of the parent element, preserving their original relative order.
- Insert the after children at the end of the parent element, preserving their original relative order.
- Let the parent element be the parent
element of the
- Remove every
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.
The noscript element is only
effective in the HTML syntax, it has no effect in
the XHTML syntax.
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.
In the following example, a noscript element is
used to provide fallback for a script.
<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>
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="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>
The above technique is also useful in XHTML, since
noscript is not supported in the XHTML
syntax.