向HTML 页面中插入JavaScript 的主要方法,就是使用<script>元素。其中HTML 4.01 为<script>定义了下列6 个属性。<script>中的JavaScript 代码将被从上至下依次解释。

language:已废弃。原来用于表示编写代码使用的脚本语言(如JavaScript、JavaScript1.2或VBScript)。

type:可选。可以看成是language 的替代属性;表示编写代码使用的脚本语言的内容类型。一般都是默认使用text/javascript。

src:可选。表示包含要执行代码的外部文件。使用<script>元素的方式有两种:1.直接在页面中嵌入JavaScript 代码和包含外部JavaScript文件。2.使用src 属性,通过<script>元素来包含外部JavaScript 文件。如果<script></script>中包含了嵌入的代码,嵌入的代码会被忽略。

//嵌入代码,只须为script标签指定type属性。
<script type="text/javascript">
    function sayHi(){
        alert("Hi!");
    }
</script>

//外部加载,使用src属性
//在外部同一个文件夹下,有example.js文件,里面是JavaScript代码
<script type="text/javascript" src="example.js"></script>

无论是否包含代码,是否使用src,只要不存在defer 和async 属性。浏览器都会按照<script>元素在页面中出现的先后顺序对它们依次进行解析。换句话说,在第一个<script>元素包含的代码解析完成后,第二个<script>包含的代码才会被解析,然后才是第三个、第四个……

按照传统的做法,所有<script>元素都应该放在页面的<head>元素中,意味着必须等到全部JavaScript 代码都被下载、解析和执行完成以后,才能开始呈现页面的内容(浏览器在遇到<body>标签时才开始呈现内容),会造成一点的延迟。而且,如果JavaScript代码中,包含对dom节点的操作,可能会报错(因为此时还没有加载页面)。为了避免这些问题,现代Web 应用程序一般都把全部JavaScript引用放在<body>元素中页面内容的后面。

//传统做法,
<!DOCTYPE html>
<html>
    <head>
        <title>Example HTML Page</title>
        <script type="text/javascript" src="example1.js"></script>
        <script type="text/javascript" src="example2.js"></script>
    </head>
    <body>
    <!-- 这里放内容 -->
    </body>
</html>

//现代做法
<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
</head>
<body>
    <!-- 这里放内容 -->
    <script type="text/javascript" src="example1.js"></script>
    <script type="text/javascript" src="example2.js"></script>
</body>
</html>

defer:表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。是表明脚本在执行时不会影响页面的构造。因此,在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。加上了defer,即使在传统的做法中(<script>元素都放在<head>中)在js脚本中,使用了对dom节点的执行操作,脚本也不会找不到dom节点了。

//在这个例子中,虽然我们把<script>元素放在了文档的<head>元素中
//但其中包含的脚本将延迟到浏览器遇到</html>标签后再执行。

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
    <script type="text/javascript" defer="defer" src="example1.js"></script>
    <script type="text/javascript" defer="defer" src="example2.js"></script>
</head>
<body>
    <!-- 这里放内容 -->
</body>
</html>

//HTML5规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,
//而这两个脚本会先于DOMContentLoaded 事件执行。
//在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件(第13章)触发前执行。
//因此最好只包含一个延迟脚本。

async:表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。只对外部脚本文件有效。但与defer不同,标记为async的脚本并不保证按照指定它们的先后顺序执行。

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
    <script type="text/javascript" async src="example1.js"></script>
    <script type="text/javascript" async src="example2.js"></script>
    </head>
<body>
    <!-- 这里放内容 -->
</body>
</html>
//在以上代码中,第二个脚本文件可能会在第一个脚本文件之前执行。
//因此,确保两者之间互不依赖非常重要。
//指定async属性的目的是减少延迟,不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。
//为此,建议异步脚本不要在加载期间修改DOM。
//在XHTML 文档中,要把async 属性设置为async="async"。

 

注意事项:

外部JavaScript文件带有.js 扩展名。但这个扩展名不是必需的,因为浏览器不会检查包含JavaScript 的文件的扩展名。因此,可以使用服务器端语言动态生成JavaScript代码。不过,需要保证请确保服务器能返回正确的脚本语言的内容类型。

src 属性还可以包含来自外部域的JavaScript 文件。这对计算机的安全提出了要求,在访问自己不能控制的服务器上的JavaScript文件时则要多加小心。

外部文件使用JavaScript的优势:可维护性(遍及不同HTML 页面的JavaScript 会造成维护问题。但把所有JavaScript 文件都放在一个文件夹中,维护起来就轻松多了。而且开发人员因此也能够在不触及HTML 标记的情况下,集中精力编辑JavaScript 代码。可缓存(浏览器能够根据具体的设置缓存链接的所有外部JavaScript 文件。也就是说,如果有两个页面都使用同一个文件,那么这个文件只需下载一次。因此,最终结果就是能够加快页面加载的速度。)适应未来(通过外部文件来包含JavaScript 无须使用前面提到XHTML 或注释hack。HTML 和XHTML 包含外部文件的语法是相同的。)

在使用<script>嵌入JavaScript 代码时,记住不要在代码中的任何地方出现"</script>"字符串。因为按照解析嵌入式代码的规则,当浏览器遇到字符串"</script>"时,就会认为那是结束的</script>标签。而通过转义字符“/”可以解决这个问题。

//浏览器在加载下面所示的代码时就会产生一个错误
<script type="text/javascript">
function sayScript(){
    alert("</script>");
}
</script>

//转义字符“/”解决
<script type="text/javascript">
function sayScript(){
    alert("<\/script>");
}
</script>

文档模式:通过使用文档类型(doctype)实现对JavaScript代码的文档要求切换。最初的两种文档模式是:混杂模式(quirks mode)和标准模式(standards mode)。混杂模式会让IE 的行为与(包含非标准特性的)IE5 相同,而标准模式则让IE 的行为更接近标准行为;

ECMAScript 5引入了严格模式(Strict mode)非严格模式(非官方称呼sloppy mode)的概念。严格模式是为JavaScript 定义了一种不同的解析与执行模型。在严格模式下,ECMAScript 3 中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。

//整个脚本都开启严格模式的语法
//外部js文件,就是直接在顶部添加"use strict";
<script type="text/javascript">
    "use strict";
    var v = "Hi!  I'm a strict mode script!";
</script>

//函数级别严格模式语法
function strict() {
  'use strict';
  function nested() { 
    return "And so am I!"; 
  }
  return "Hi!  I'm a strict mode function!  " + nested();
}
//非严格模式
function notStrict() { 
  return "I'm not strict."; 
}

早期浏览器都面临一个特殊的问题,即当浏览器不支持JavaScript 时如何让页面平稳地退化(现在,基本已经没有这个问题了)。对这个问题的最终解决方案就是创造一个<noscript>元素,用以在不支持JavaScript 的浏览器中显示替代的内容。这个元素可以包含能够出现在文档<body>中的任何HTML 元素——<script>元素除外。包含在<noscript>元素中的内容只有在下列情况下才会显示出来:

<html>
<head>
    <title>Example HTML Page</title>
    <script type="text/javascript" defer="defer" src="example1.js"></script>
    <script type="text/javascript" defer="defer" src="example2.js"></script>
</head>
<body>
    <noscript>
        <p>本页面需要浏览器支持(启用)JavaScript。
    </noscript>
</body>
</html>
//这个页面会在脚本无效的情况下向用户显示一条消息。
//而在启用了脚本的浏览器中,用户永远也不会看到它——尽管它是页面的一部分。