转自原文 <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,原因最后说明),问题如下


<script type="text/javascript">//<![CDATA[
        document.write('<script type="text/javascript" src="test.js"><\/script>');       
   document.write('<script type="text/javascript">');       
    document.write('alert("222");')       
    document.write('alert("变量保存值" + tmpStr);');       
    document.write('<\/script>');        //]]>
</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>标签的加载解析执行的更多相关文章

  1. 【JavaScript性能优化】------理解Script标签的加载和执行

    1.script标签是如何加载的?当浏览器遇到一个 < script>标签时,浏览器会停下来,运行JavaScript代码,然后再继续解析.翻译页面.同样的事情发生在使用 src 属性加载 ...

  2. 动态script标签同步加载 ps:无打包编译,静态实现静态资源入口动态配置,无编译打包静态资源添加版本号

    /**功能:创建动态标签加载css ,js文件,重点是js文件,利用onloading加递归实现动态标签的同步加载用法:在html文件body底部script内部声明并调用下列函数,obj中写要加载的 ...

  3. js——<script>标签的加载顺序

    用了很久的JavaScript,今天突然就碰见了将一个js文件放在<head></head>与<body></body>标签中,一个不可以执行,一个可以 ...

  4. 【javascript】script标签的async异步解析

    <script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染 ...

  5. 重操JS旧业第一弹:Script与JS加载

    不管js被包装成什么样子,最终交给浏览器执行的js都是原生的,都离不开原生js的原理. Script标签纸html中用来加载js的标签,我们知道js可以是来自外部,本地,或者内部一段代码,在这里只讨论 ...

  6. JavaScript 的性能优化:加载和执行

    随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 ...

  7. 浏览器中Javascript的加载和执行

    在刚学习Javascript时曾对该问题在小组内做个一次StudyReport,发现其中的基础还是值得分析的. 从标题分析,可以加个Javascript的加载和执行分为两个阶段:加载.执行.而加载即浏 ...

  8. 高性能JavaScript-JS脚本加载与执行对性能的影响

    在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 脚本位置对性能的影响 优化页面加载性能的原则之一是将scri ...

  9. [转]JavaScript 的性能优化:加载和执行

    原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化: ...

随机推荐

  1. akka设计模式系列-Aggregate模式

    所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同.masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑 ...

  2. 基于Spark Streaming预测股票走势的例子(一)

    最近学习Spark Streaming,不知道是不是我搜索的姿势不对,总找不到具体的.完整的例子,一怒之下就决定自己写一个出来.下面以预测股票走势为例,总结了用Spark Streaming开发的具体 ...

  3. url参数为数组

    //url中state参数为数组 ?baseline_id=12&version_id=34&state[]=complete&state[]=hangup&state ...

  4. 【Leetcode 220】 Contains Duplicate III

    问题描述:判断数组中是否存在<ai aj> abs(ai - aj)<=t  && abs(i - j) <=k: 问题分析:需要一个数据结构来维护满足条件k. ...

  5. 【原】cocos2d-x开发笔记:获取Sprite上某一个点的透明度,制作不规则按钮

    本篇文章主要讲一下怎么做一个不规则的按钮,比如如下图的八卦,点击绿色和点击红色部分,需要执行不同的事件

  6. 慕课网中网页定位导航中js相关问题总结

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title> ...

  7. SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础

    SAS学习笔记之<SAS编程与数据挖掘商业案例>(1)系统简介和编程基础 1. SAS系统简介 1.1 SAS是先编译后执行的语言,data步标志着编译的开始. 数据指针:当前内存缓存区, ...

  8. android中textview单行显示,多余的省略

    <TextView android:id="@+id/music_title" android:layout_width="wrap_content" a ...

  9. Hibernate 延迟加载剖析与代理模式应用

    本文来源于:http://www.ibm.com/developerworks/cn/java/j-lo-hibernatelazy/#icomments

  10. flask web开发日记

    from flask import Flask,make_response,redirect,abort app = Flask(__name__) @app.route('/index1') def ...