没有合适的资源?快使用搜索试试~ 我知道了~
本文主要基于向HTML页面引入JavaScript的几种方式,分析HTML中JavaScript脚本的执行顺序问题,通过本文给大家分享浏览器执行JavaScript脚本加载与代码执行顺序,对浏览器执行javascript及执行顺序相关知识感兴趣的朋友一起学习吧
资源推荐
资源详情
资源评论
探析浏览器执行探析浏览器执行JavaScript脚本加载与代码执行顺序脚本加载与代码执行顺序
本文主要基于向HTML页面引入JavaScript的几种方式,分析HTML中JavaScript脚本的执行顺序问题,通过本文给大家分享浏览器执行JavaScript脚本加载与代码执行顺序,对浏览
器执行javascript及执行顺序相关知识感兴趣的朋友一起学习吧
本文主要基于向HTML页面引入JavaScript的几种方式,分析HTML中JavaScript脚本的执行顺序问题
1. 关于关于JavaScript脚本执行的阻塞性脚本执行的阻塞性
JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析、渲染以及其他资源的下载都要停下来等待脚本执行完毕①。这一点是没有争议的,并且在所有
浏览器中的行为都是一致的,原因也不难理解:浏览器需要一个稳定的DOM结构,而JavaScript可能会修改DOM(改变DOM结构或修改某个DOM节点),如果在JavaScript执行的同时还继续进行页面的解
析,那么整个解析过程将变得难以控制,解析出错的可能也变得很大。
然而这里还有一个问题需要注意,对于外部脚本,还涉及到一个脚本下载的过程,在早期的浏览器中,JavaScript文件的下载不仅会阻塞页面的解析,甚至还会阻塞页面其他资源的下载(包括其他
JavaScript脚本文件、外部CSS文件以及图片等外部资源)。从IE8、firefox3.5、safari4和chrome2开始允许JavaScript并行下载,同时JavaScript文件的下载也不会阻塞其他资源的下载(旧版本
中,JavaScript文件的下载也会阻塞其他资源的下载)。
注:不同浏览器对于同一个域名下的最大连接数有不同的限制,HTTP1.1协议规范中的要求是不能高于2个,但是大多数浏览器目前实际提供的最大连接数都多于2个,IE6/7都是2个,IE8提升到了6
个,firefox和chrome也是6个,当然这个设置也是可以修改的,详细内容可以参考:http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/
2. 关于脚本的执行顺序关于脚本的执行顺序
浏览器是按照从上到下的顺序解析页面,因此正常情况下,JavaScript脚本的执行顺序也是从上到下的,即页面上先出现的代码或先被引入的代码总是被先执行,即使是允许并行下载JavaScript文件时也
是如此。注意我们这里标红了"正常情况下",原因是什么呢?我们知道,在HTML中加入JavaScript代码有多种方式,概括如下(不考虑requirejs或seajs等模块加载器):
(1)正常引入:即在页面中通过<script>标签引入脚本代码或者引入外部脚本
(2)通过document.write方法向页面写入<script>标签或代码
(3)通过动态脚本技术,即利用DOM接口创建<script>元素,并设置元素的src,然后再将元素添加进DOM中。
(4)通过Ajax获取脚本内容,然后再创建<script>元素,并设置元素的text,再将元素添加进DOM中。
(5)直接把JavaScript代码写在元素的事件处理程序中或直接作为URL的主体,示例如下:
<!--直接写在元素的事件处理程序中-->
<input type="button" value="点击测试一下" onclick="alert('点击了按钮')"/>
<!--作为URL的主体-->
<a href="javascript:alert('dd')">JS脚本作为URL的主体</a>
第5种情况对于我们讨论的脚本执行顺序没有什么影响,因此我们这里只讨论前四种情况:
2.1 正常引入脚本时正常引入脚本时
正常引入脚本时,JavaScript代码会按照从上到下的顺序执行,不管脚本是不是并行下载,执行时还是按照引入的顺序从上到下执行的,我们以下面的DEMO为例:
首先,通过PHP写了一个脚本,这个脚本接收两个参数,文件URL和延迟时间,脚本会在传入的延迟时间之后,将文件内容发送给浏览器,脚本如下:
<?php
$url = $_GET['url'];
$delay = $_GET['delay'];
if(isset($delay)){
sleep($delay);
}
echo file_get_contents($url);
?>
另外我们还定义了两个JavaScript文件,分别为1.js和2.js,在这个例子中,二者的代码分别如下:
1.js
alert("我是第一个脚本");
2.js
alert("我是第二个脚本");
然后,我们在HTML中引入脚本代码:
<script src='/delayfile.php?url=http://localhost/js/load/1.js&delay=3' type='text/javascript'></script>
<script type="text/javascript">
alert("我是内部脚本");
</script>
<script src='/delayfile.php?url=http://localhost/js/load/2.js&delay=1' type='text/javascript'></script>
虽然第一个脚本延迟了3秒才会返回,但是在所有浏览器中,弹出的顺序也都是相同的,即:"我是第一个脚本"->"我是内部脚本"->"我是第二个脚本"
2.2 通过通过document.write向页面中写入脚本时向页面中写入脚本时
document.write在文档流没有关闭的情况下,会将内容写入脚本所在位置结束之后紧邻的位置,浏览器执行完当前短的代码,会接着解析document.write所写入的内容。
注:document.write写入内容的位置还存在一个问题,加入在<head>内部的脚本中写入了<head>标签内部不应该出现的内容,比如<div>等内容标签等,则这段内容的起始位置将是<body>标签的起始位
置。
通过document.write写入脚本时存在一些问题,需要分类进行说明:
[1]同一个<script>标签中通过document.write只写入外部脚本:
在这种情况下,外部脚本的执行顺序总是低于引入脚本的标签内的代码,并且按照引入的顺序来执行,我们修改HTML中的代码:
<script src='/delayfile.php?url=http://localhost/js/load/1.js&delay=2' type='text/javascript'></script>
<script type="text/javascript">
document.write('<script type="text/javascript" src="/delayfile.php?url=http://localhost/js/load/2.js"><\/script>');
document.write('<script type="text/javascript" src="/delayfile.php?url=http://localhost/js/load/1.js"><\/script>');
alert("我是内部脚本");
</script>
这段代码执行完毕之后,DOM将被修改为:
而代码执行的结果也符合DOM中脚本的顺序:"我是第一个脚本"->"我是内部脚本"->"我是第二个脚本"->"我是第一个脚本"
[2]同一个<script>标签中通过document.write只写入内部脚本:
在这种情况下,通过documen.write写入的内部脚本,执行顺序的优先级与写入脚本标签内的代码相同,并且按照写入的先后顺序执行:
我们再修改HTML代码如下:
<script src='/delayfile.php?url=http://localhost/js/load/1.js' type='text/javascript'></script>
<script type="text/javascript">
document.write('<script type="text/javascript">alert("我是docment.write写入的内部脚本")<\/script>');
alert("我是内部脚本");
document.write('<script type="text/javascript">alert("我是docment.write写入的内部脚本2222")<\/script>');
document.write('<script type="text/javascript">alert("我是docment.write写入的内部脚本3333")<\/script>');
</script>
在这种情况下,document.write写入的脚本被认为与写入位置处的代码优先级相同,因此在所有浏览器中,弹出框的顺序均为:"我是第一个脚本"->"我是document.write写入的内部脚本"->"我是内部脚
本"->"我是document.write写入的内部脚本2222"->"我是document.write写入的内部脚本3333"
资源评论
weixin_38660579
- 粉丝: 11
- 资源: 918
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功