<script>标签的加载解析执行
转自原文 <script>标签的加载解析执行
看了很多网上的文章,都是大同小异。总结一下。内部原理还没有搞清楚,有机会再学习。
一、<script>标签的加载解析执行顺序
html页面中的<script>标签中的内容(直接写入或者引用外部文件都一样)是以顺序加载执行的,每个<script>标记内容可以当成一个独立的块,同步的情况下一个块加载解析然后执行完后才加载下一块。当然这时也会阻塞其他页面元素的加载。所以网上说的变量调用:
<script type="text/javascript">//<![CDATA[
alert(tmp); //输出 undefined
var tmp = '111';
alert(tmp); //输出 111
//]]>
</script>
还有函数调用:
<script type="text/javascript">//<![CDATA[
test(); //浏览器报错
//]]>
</script>
<script type="text/javascript">//<![CDATA[
test(); //输出 fun!
function test(){alert('fun!');}
//]]>
</script>
其实很简单,对于变量,在一个作用域中在变量声明前面使用变量,本来就是undifined(解析过程中已经知道有这个变量, 但没赋值,等到执行才赋值)。对于函数,同一块中可以,因为解析的时候已经知道有那个函数了,但是分在不同块中,当test 调用时,下面声明test函数的内容根本还没被加载进来,所以调用出错。
二、document.write ()问题
本来这样不就挺好吗。但是来个document.write就坑爹了。先摘一段网上的话::“输出写入到脚本文档所在的位置,浏览器解析完documemt.write()所在文档内容后,继续解析document.write()输出的内容,然后在继续解析HTML文档”。
测试过,在一个<script>标记中通过document.write()输出的内容会依次插到该标记的后面(动态加载)。但插入内容没有解析和执行, 解析执行还是按文档顺序下来,等到执行完documemt.write()所在的script标记的内容后再解析执行。但是这仅限于document.write 方式没有写入可引用的外部文件并且引入文件内不包含document.write时的情况。
关于引入外部文件与外部文件包含document.write参考自http://w3help.org/zh-cn/causes/BX9014。
例子见参考,内容大概就是:第一,当document.write方式引入的外部文件里面包含document.write写入流,IE 是在当前 SCRIPT 标记内所有的 document.write 向文档中输出内容完成后,再处理以 document.write 方式引入的 JS 文件内的 document.write 写入流。对于其他浏览器,则根据代码执行顺序依次处理 document.write 方式写入的内容(但测试过,外部文件中除document.write外的内容对于ie和firefox一样,是等到当前 SCRIPT 标记执行结束后才执行的)。第二,当使用 document.write 方式写入可引用的外部JavaScript 内容后,非 IE Opera 浏览器并不会立即更新 DOM 树。
对于第二点,我觉得恰好可以解释网上所说的一个问题(没有debug,原因最后说明),问题如下
document.write('<script type="text/javascript" src="test.js"><\/script>');
<script type="text/javascript">//<![CDATA[
alert("333"); //]]>
</script>
test.js的内容是:
var tmpStr = '111'; alert(tmpStr);
在Firefox和Opera中的弹出值的顺序是:111、222、变量保存值111、333
在IE中弹出值的顺序是:222、111、333, 同时浏览器报错:tmpStr未定义
原因可能是IE在document.write时,并未等待加载SRC中的Javascript代码完毕后,才执行下一行,所以导致222先弹出,并且执行到document.write(‘document.write(“变量保存值” + tmpStr)’)调用tmpStr时,tmpStr并未定义,从而报错。
但是我觉得原因不是这个,原因应该就是其他浏览器没有立即更新dom树。IE会在document.write('<script type="text/javascript" src="test.js"><\/script>')后更新dom树,此时dom树中引用test文件的<script>节点已存在,后续插入的<script>节点都会被插入在正在执行的<script>的后面,也就是引入test文件的<script>节点的前面。所以执行alert时test内容还没执行。而其他浏览器是当<script>的内容执行完毕后再更新dom树,所以document.write写入的内容是以顺序添加到包含他们的<script>后面的。当然这只是我个人理解,如果错误还请看到的人指出。
最后一个问题,对于使用document.write时出现的firefox和IE间的处理不一致,当我firefox用debug设断点调试(一步一步跳)时竟然变得跟IE一致了。像上面那个例子firefox断点调试时竟然tempStr也是notdefined,引入的文件没有跳进去。js我也是学得不久有懂的请赐教。
花了一天还没搞明白,真不知道去抠这些问题有没有价值,觉得还是少用document.write吧。
<script>标签的加载解析执行的更多相关文章
- 【JavaScript性能优化】------理解Script标签的加载和执行
1.script标签是如何加载的?当浏览器遇到一个 < script>标签时,浏览器会停下来,运行JavaScript代码,然后再继续解析.翻译页面.同样的事情发生在使用 src 属性加载 ...
- 动态script标签同步加载 ps:无打包编译,静态实现静态资源入口动态配置,无编译打包静态资源添加版本号
/**功能:创建动态标签加载css ,js文件,重点是js文件,利用onloading加递归实现动态标签的同步加载用法:在html文件body底部script内部声明并调用下列函数,obj中写要加载的 ...
- js——<script>标签的加载顺序
用了很久的JavaScript,今天突然就碰见了将一个js文件放在<head></head>与<body></body>标签中,一个不可以执行,一个可以 ...
- 【javascript】script标签的async异步解析
<script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染 ...
- 重操JS旧业第一弹:Script与JS加载
不管js被包装成什么样子,最终交给浏览器执行的js都是原生的,都离不开原生js的原理. Script标签纸html中用来加载js的标签,我们知道js可以是来自外部,本地,或者内部一段代码,在这里只讨论 ...
- JavaScript 的性能优化:加载和执行
随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 ...
- 浏览器中Javascript的加载和执行
在刚学习Javascript时曾对该问题在小组内做个一次StudyReport,发现其中的基础还是值得分析的. 从标题分析,可以加个Javascript的加载和执行分为两个阶段:加载.执行.而加载即浏 ...
- 高性能JavaScript-JS脚本加载与执行对性能的影响
在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 脚本位置对性能的影响 优化页面加载性能的原则之一是将scri ...
- [转]JavaScript 的性能优化:加载和执行
原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化: ...
随机推荐
- php的session
来源:http://blog.163.com/lgh_2002/blog/static/4401752620105246517509/ http协议是WEB服务器与客户 端(浏览器)相互通信的协议,它 ...
- jQuery获取Select元素
jQuery获取Select元素,并选择的Text和Value: 1. $("#select_id").change(function(){//code...}); //为Se ...
- Codeforces 792C
题意:给出一个由0到9数字构成的字符串,要求删去最少的数位,使得这个字符串代表的数能被3整除,同时要求不能有前导零,并且至少有一位(比如数字11,删去两个1后就没有数位了,所以不符合).如果能够处理出 ...
- Offer收割_4
1.水题 2.BFS宽搜(使用优先队列priority_queue) 4.题意:给数组a.要求重排列数组,使得数组中的任意相邻的两个元素不同.如果存在多个方案,那么选择字典序最小的方案. 如果不能满 ...
- Unity实现屏幕抖动效果(通过Camera Viewpoint实现)
由于游戏死亡时一般都需要屏幕抖一下下. 所以百度了下相关写法,发现方法很多~~~ 找来找去,找到个简单粗暴地,啥都不需要,一个脚本拖动到Camera上就可以了 略微修改了一点点,share一下 usi ...
- centos7安装mysql和mysql-connector-c++
最近为了搭建自己的开发环境,又一次在centos7上面开始安装mysql和c++的访问环境,特此记录一下搭建过程,方便以后查阅 一.安装mysql centos7 默认安装了mariaDB,导致不能安 ...
- tp5.0分页样式调控
基础的分页调用 /** * 控制器部分代码 */ //实例化模型 $areasModel=new Areas(); //分页数据集 $listarea=$areasModel->paginate ...
- 笔记《精通css》第5章 链接应用样式
第5章 链接应用样式 1.链接伪类选择器 a : link{ } (寻找没有被访问过的链接) a : visied{ }(寻找被访问过的链接) 动态伪类选择器 a : hover ...
- Kotlin实例----android5.0新特性之palette
一.Palette的使用 使用Palette可以让我们从一张图片中拾取颜色,将拾取到的颜色赋予ActionBar,StatusBar以及UI背景色可以让界面色调实现统一或者加载不同图片时同步变化色调 ...
- JS——样式类的添加
1.注意current前有个空格 this.className = this.className + " current"; 2.直接将class所有的值替换成current th ...