|
1.3 JavaScript脚本运行机制 |
上一节介绍了HTML网页中的JavaScript脚本语言,并通过实例演示了JavaScript脚本代码在网页中执行的结果。我们知道JavaScript脚本代码可以放在HTML网页中的任何位置,比如在页面头部<head>标签内、页面主体<body>标签内、又或者是页面<body>标签之后。那么,这样就会带来一个问题,那就是JavaScript脚本代码在页面中的不同位置有没有什么区别呢?
要想解答这个疑问,就要先理解HTML网页的运行机制。HTML网页是按照页面代码定义的先后顺序,自上而下依次执行的。我们在浏览网页时就会发现,页面内容是自上而下显示出来的。举一个例子大家就明白了,早期在个人家庭中接入互联网一般是使用调制解调器(Modem),当时的带宽都是56Kb或128Kb的,因此网速很慢甚至很卡。经常会遇到浏览器k网页的内容显示到一半就卡住不动了,不过这恰恰解释了HTML网页的执行顺序。只不过如今个人家庭中都是百兆、甚至千兆宽带接入,网速非常快,大家在打开网页时也就体会不到HTML页面自上而下的执行顺序。
理解了HTML网页的运行机制,我们继续讲解JavaScript脚本代码的运行机制。对于定义在页面中的JavaScript脚本代码,会随着HTML网页自上而下的顺序执行。只不过,JavaScript脚本代码是按照中断机制执行的,也就是说HTML网页遇到JS代码时会中止执行,直到JS脚本解析完成后网页才会继续运行。那么问题就来了,JavaScript脚本代码在HTML网页中定义的位置会对浏览器页面内容的显示产生很大的影响。
下面,先看一个将JavaScript脚本代码定义在页面头部<head>标签中的实例(一般初学者的常规做法),具体代码如下(详见源代码ch01目录中ch01-js-run-in-head.html文件)。
【代码1-4】
01 <!doctype html> 02 <html lang="en"> 03 <head> 04 <!-- 添加文档头部内容 --> 05 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 06 <meta http-equiv="Content-Language" content="zh-cn" /> 07 <link rel="stylesheet" type="text/css" href="css/style.css"> 08 <script> 09 alert("JavaScript脚本代码定义在页面头部head标签元素内."); 10 </script> 11 <title>JavaScript in 15-days</title> 12 </head> 13 <body> 14 <!-- 添加文档主体内容 --> 15 <header> 16 <nav>JavaScript 基础 - js脚本代码运行机制</nav> 17 </header> 18 <hr> 19 <!-- 添加文档主体内容 --> 20 <h3>正文</h3> 21 <p> 22 JavaScript脚本代码定义在页面头部head标签元素内. 23 </p> 24 </body> 25 </html>
关于【代码1-4】的分析如下:
第08~10行代码通过<script>标签定义一段嵌入式JavaScript脚本代码,第09行的JS代码通过“alert()”函数定义了一个弹出式警告提示框;
第13~24行代码在<body>标签内定义了一些页面内容,具体包括标题和正文文本。
下面运行测试【代码1-4】定义的HTML页面,查看一下JavaScript脚本代码的执行结果,具体如图1.4所示。第08~10行代码定义的警告提示框弹出来了,但页面中定义的文本内容却没有显示出来,浏览器窗口还是灰色的。这恰恰说明JavaScript脚本代码的中断执行机制,由于本例中JS脚本定义在<head>标签内,因此页面内容还没有加载完成就被JS脚本中断了。单击警告提示框中的“确定”按钮将JS代码执行完成,具体结果如图1.5所示。直到JavaScript脚本代码执行完成后,页面内容才会加载完成并显示在浏览器中。
图1.4 定义在页面头部的JavaScript脚本(1)
图1.5 定义在页面头部中的JavaScript脚本(2)
接下来介绍将JavaScript脚本代码定义在页面主体<body>标签中的实例(JS脚本是允许定义在HTML页面中的任何位置),具体代码如下(详见源代码ch01目录中ch01-js-run-in-body.html文件)。
【代码1-5】
01 <!doctype html> 02 <html lang="en"> 03 <head> 04 <!-- 添加文档头部内容 --> 05 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 06 <meta http-equiv="Content-Language" content="zh-cn" /> 07 <link rel="stylesheet" type="text/css" href="css/style.css"> 08 <title>JavaScript in 15-days</title> 09 </head> 10 <body> 11 <!-- 添加文档主体内容 --> 12 <header> 13 <nav>JavaScript 基础 - js脚本代码运行机制</nav> 14 </header> 15 <hr> 16 <!-- 添加文档主体内容 --> 17 <script> 18 alert("JavaScript脚本代码定义在页面主体body标签元素内."); 19 </script> 20 <h3>正文</h3> 21 <p> 22 JavaScript脚本代码定义在页面主体body标签元素内. 23 </p> 24 </body> 25 </html>
关于【代码1-5】的分析如下:
第17~19行代码通过<script>标签定义了一段嵌入式JavaScript脚本代码,其定义位置是在页面主体<body>标签中。第18行的JS代码通过“alert()”函数定义了一个弹出式警告提示框。
在第17~19行JS脚本代码的前后,分别定义了一些页面内容,具体包括标题和正文文本。
下面运行测试【代码1-5】定义的HTML页面,查看一下JavaScript脚本代码的执行结果,具体如图1.6所示。
图1.6 定义在页面主体中的JavaScript脚本(1)
如图1.6所示,第17~19行代码定义的警告提示框弹出来了。同时,大家注意图中箭头指向的内容,第12~14行代码定义的页面标题和第15行代码水平分割线已经显示出来了,但第20~23行代码定义的页面正文却没有显示出来。
这同样是因为JavaScript脚本代码的中断执行机制起的作用,由于本例中JS脚本定义在第17~19行,正好在页面文本内容的中间。
单击警告提示框中的“确定”按钮将JS代码执行完成,具体结果如图1.7所示。
图1.7 定义在页面主体中的JavaScript脚本(2)
通过图1.7可知直到JavaScript脚本代码执行完成后,后面的页面内容才加载完成显示在浏览器中。
最后介绍将JavaScript脚本代码定义在页面主体<body>标签后的实例(之后会有总结分析),具体代码如下(详见源代码ch01目录中ch01-js-run-in-end.html文件)。
【代码1-6】
01 <!doctype html> 02 <html lang="en"> 03 <head> 04 <!-- 添加文档头部内容 --> 05 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 06 <meta http-equiv="Content-Language" content="zh-cn" /> 07 <link rel="stylesheet" type="text/css" href="css/style.css"> 08 <title>JavaScript in 15-days</title> 09 </head> 10 <body> 11 <!-- 添加文档主体内容 --> 12 <header> 13 <nav>JavaScript 基础 - js脚本代码运行机制</nav> 14 </header> 15 <hr> 16 <!-- 添加文档主体内容 --> 17 <h3>正文</h3> 18 <p> 19 JavaScript脚本代码定义在页面主体body标签元素后. 20 </p> 21 </body> 22 <script type="text/javascript" src="js/ch01-js-run-in-end.js"></script> 23 </html>
关于【代码1-6】的分析如下:
第10~21行代码在页面主体<body>标签内定义了一些页面内容,具体包括标题和正文文本;
第22行代码通过<script>标签定义了外链式JavaScript脚本,其中“src”属性定义了外部脚本的相对路径地址("js/ch01-js-run-in-end.js")。这里JavaScript脚本的位置是放在了<body>标签后的,也就是HTML网页的最后。
关于上面引入的外部脚本文件的具体代码如下(详见源代码ch01目录中js/ch01-js-run-in-end.js文件)。
【代码1-7】
01 alert("JavaScript脚本代码定义在页面主体body标签元素后.");
关于【代码1-7】的分析如下:
第01行JS代码通过“alert()”函数定义了一个弹出式警告提示框,与前面两个实例的JS脚本功能类似。
下面运行测试【代码1-6】定义的HTML页面,查看一下JavaScript脚本代码的执行结果,具体如图1.8所示。
图1.8 定义在页面最后的JavaScript脚本(1)
从图1.8看出,第17~19行代码定义的警告提示框弹出来了。同时,大家注意图中箭头指向的内容(部分内容被弹出框遮盖了),第10~21行代码定义的页面内容已经全部显示出来了。
这就说明本例中在页面主体<body>标签后引用的JS脚本是在页面内容全部加载完成后执行的,与JavaScript脚本定义的位置是一致的。单击警告提示框中的“确定”按钮将JS代码执行完成,具体结果如图1.9所示。
图1.9 定义在页面最后的JavaScript脚本(2)
通过以上三个实例,我们大致了解JavaScript脚本代码在HTML网页中定义的位置对页面执行结果的影响。那么,简单总结一下关于JavaScript脚本代码的位置在HTML网页中定义要遵循的几个原则。
(1)尽可能地将JavaScript脚本代码(包括嵌入式和外链式)放在<body>标签之后,这样在HTML网页内容加载时就不会因为JavaScript脚本的中断执行机制而延迟阻塞,自然就会提高页面的显示速度。
(2)如果要实现一些页面特效,而需要预先动态加载一些JavaScript脚本代码,那么这些JS脚本就应该放在<head>标签内或<body>标签的前面。因此,对于“全部JavaScript脚本代码要放在页面的最后便于提高加载速度”的说法并不可靠。可见上述的第一条原则并不是通用的,因情况而异。
(3)对于需要使用JavaScript脚本代码动态访问操作页面DOM元素的情况,要将JS脚本放在DOM元素定义之后(当然依据第一条原则,最好统一放在<body>标签之后);如果放在DOM元素定义之前,由于DOM元素还没有生成,必然会产生JS脚本访问错误或无效操作的情况。
以上三条就是JavaScript脚本代码定义位置需要遵循的大致原则,当然这不是硬性规定,而是根据经验总结出来的比较不错的方法。