本篇内容
  • <script>元素
  • <noscript>元素
  • <script>元素的位置
  • 延迟脚本和异步脚本

<script>元素

<script>标签用于定义客户端脚本,向HTML页面中插入JavaScript的主要方法,就是使用<script>元素。(该元素由Netscape创造后被加入到正式的HTML规范中)

1.<script>标签的部分属性:

属性 描述
async(HTML5) async 表示应该立即下载脚本,但不应该妨碍页面中的其他操作(异步执行脚本)。仅适用于外部脚本。
charset charset 指定代码的字符集。仅适用于外部脚本。(大部分浏览器会忽略)
defer defer 表示脚本可以延迟到文档完全被解析和显示之后再执行。仅适用于外部脚本。
language script (废弃)表示编写代码使用的脚本语言。
src URL 表示包含要执行代码的外部文件URL。
type MIME-type 表示编写代码使用的脚本语言的内容类型(MIME类型)。考虑到约定俗成和最大限度的浏览器兼容性,目前type属性的值依旧还是text/javascript。不过,这个属性并不是必需的,如果没有指定这个属性,则其默认值仍为text/javascript。

2.<script>的使用方式:

使用<script>元素的方式有两种:直接在页面中嵌入JavaScript代码和包含外部JavaScript文件。

2.1 在使用<script>元素嵌入JavaScript代码时,只须为<script>指定type属性。然后把JavaScript代码放入元素内。如:
1
2
3
4
5
<script type="text/javascript">
function sayHi() {
alert('Hi man');
}
</script>

包含在元素内部的JavaScript代码将被从上至下依次解析。如前面这个例子,解释器会解释一个函数的定义,然后将该定义保存在自己的环境中,在解释器对<script>元素内部的所有代码求值完毕以前,页面中的其余内容不会被浏览器加载或显示。

注意:在使用<script>嵌入JavaScript代码时,不要在代码中的任何地方出现“</script>”字符串。例如下面所示的代码在浏览器里就会产生一个错误:

1
2
3
4
5
<script type="text/javascript">
function sayHi() {
alert('</script>');
}
</script>

原因:按照解析嵌入代码的规则,当浏览器遇到字符串“</script>”时,就会认为那是结束的</script>标签。
解决方法:通过转义字符“/”。如:

1
2
3
4
5
<script type="text/javascript">
function sayHi() {
alert('<\/script>');
}
</script>
2.2 引入外部JavaScript文件

此时src属性为必需的,这个属性的值就是一个指向外部JavaScript文件的链接(可以来自外域)。如:

1
<script type="text/javascript" src="js/example.js"></script>

与解析嵌入式JavaScript代码一样,在解析外部JavaScript文件(包括下载该文件)时,页面的处理也会暂时停止。

注意:带有src属性的<script>元素不应该在其<script></script>标签之间再包含额外的JavaScript代码(这部分代码会被忽略)。

按照惯例,外部JavaScript文件带有.js扩展名。但这个拓展名不是必需的,因为浏览器不会检查包含JavaScript的文件的拓展名。这样一来,使用JSP、PHP或其他服务器端语言动态生成JavaScript代码也就成为了可能。但是,服务器通常还是需要看拓展名决定为响应应用哪种MIME类型。如果不使用拓展名,请确保服务器能返回正确的MIME类型。

只要不存在defer和async属性,浏览器都会按照<script>元素在页面中出现的先后顺序对他们依次进行解析。

<noscript>元素

noscript 元素用来定义在脚本未被执行时的替代内容(文本)。此标签可被用于可识别 <script>标签但无法支持其中的脚本的浏览器。
<noscript>元素中的内容只有在下列情况下才会显示出来:

  • 浏览器不支持脚本
  • 浏览器支持脚本,但脚本被禁用

例:

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/vbscript">
document.write("Hello JavaScript!")
</script>

<noscript>这浏览器不支持JavaScript!</noscript>
</body>
</html>

<script>元素的位置

<script>元素的位置主要为两种:<head>标签和</head>标签之间;</body>标签之前。

1.<head>标签和</head>标签之间

如:

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<meta charset="utf-8">
<script src="example1.js"></script>
<script src="example2.js"></script>
</head>
<body>
...
</body>
</html>

这种做法的目的就是把所有外部文件(包括CSS和js文件)的引用都放在相同的地方,方便管理。
缺陷:
在文档的<head>元素中包含所有JavaScript文件,意味着必须等到全部JavaScript代码都被下载、解析和执行完以后,才能开始呈现内容(浏览器在遇到<body>标签时才开始呈现内容)。
html文件是自上而下的执行方式,但引入的css和js的顺序有所不同,css引入执行加载时,程序仍然往下执行,而执行到<script>脚本是则中断线程,待该script脚本执行结束之后程序才继续往下执行。其次,需要访问DOM元素的js放在body之前会出错,因为此时还没有开始生成DOM。

2.在</body>之前

如:

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<meta charset="utf-8">
</head>
<body>
...

<script src="example1.js"></script>
<script src="example2.js"></script>
</body>
</html>

在解析包含的JavaScript代码之前,页面的内容将完全被呈现在浏览器中。

延迟脚本和异步脚本

1.延迟脚本defer

<script>这个属性的用途是表明脚本在执行时立即下载延迟执行(浏览器遇到</html>标签后再执行,若此时已加载完则优先于DOMContentLoaded事件),不会影响页面的构造,也就是说脚本会延迟到整个页面都解析完毕后再运行。
如:

1
<script defer="defer" src="example.js"></script>

注意:延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,因此最好只包含一个延迟脚本。

2.异步脚本async

<script>这个属性与async类似,都用于改变处理脚本的行为。异步加载和执行脚本,在页面的load事件前执行,但可能在DOMContentLoaded事件触发之前或之后执行。
如:

1
<script async="async" src="example.js"></script>

至于书中的《在XHTML中的用法》此篇不作介绍,几乎用不到。

温习:

  • <script>标签、主要属性、用法和在HTML中的位置
  • <noscript>标签
  • 延迟脚本和异步脚本的相关属性已经处理顺序

(完)