Javascript代码在页面加载时的执行顺序介绍


Posted in Javascript onMay 03, 2013

一、在HTML中嵌入Javasript的方法
1.直接在Javascript代码放在标记对<script>和</script>之间
2.由<script />标记的src属性制定外部的js文件
3.放在事件处理程序中,比如:<p onclick="alert('我是由onclick事件执行的Javascript')">点击我</p>
4.作为URL的主体,这个URL使用特殊的Javascript:协议,比如:<a href="javascript:alert('我是由javascript:协议执行的javascript')">点击我</a>
5.利用javascript本身的document.write()方法写入新的javascript代码
6.利用Ajax异步获取javascript代码,然后执行
 

第3种和第4种方法写入的Javascript需要触发才能执行,所以除非特别设置,否则页面加载时不会执行。

二、Javascript在页面的执行顺序
1.页面上的Javascript代码是HTML文档的一部分,所以Javascript在页面装载时执行的顺序就是其引入标记<script />的出现顺序, <script />标记里面的或者通过src引入的外部JS,都是按照其语句出现的顺序执行,而且执行过程是文档装载的一部分。
2.每个脚本定义的全局变量和函数,都可以被后面执行的脚本所调用。
3.变量的调用,必须是前面已经声明,否则获取的变量值是undefined。

<script type="text/javscrpt">//<![CDATA[
alert(tmp);  //输出 undefined
var tmp = 1;
alert(tmp);  //输出 1
//]]></script>

4.同一段脚本,函数定义可以出现在函数调用的后面,但是如果是分别在两段代码,且函数调用在第一段代码中,则会报函数未定义错误。
<script type="text/javscrpt">//<![CDATA[
aa();            //浏览器报错
//]]></script>
<script type="text/javscrpt">//<![CDATA[
aa();   //输出 1 
function aa(){alert(1);}
//]]></script>

5.document.write()会把输出写入到脚本文档所在的位置,浏览器解析完documemt.write()所在文档内容后,继续解析document.write()输出的内容,然后在继续解析HTML文档。
<script type="text/javascript">//<![CDATA[
    document.write('<script type="text/javascript" src="test.js"><\/script>');
    document.write('<script type="text/javascript">');
    document.write('alert(2);')
    document.write('alert("我是" + tmpStr);');
    document.write('<\/script>');
    //]]></script>
  <script type="text/javascript">//<![CDATA[
    alert(3);
    //]]></script>

test.js的内容是:
var tmpStr = 1;
alert(tmpStr);

•在Firefox和Opera中的弹出值的顺序是:1、2、我是1、3
•在IE中弹出值的顺序是:2、1、3,同时浏览器报错:tmpStr未定义
原因可能是IE在document.write时,并未等待加载SRC中的Javascript代码完毕后,才执行下一行,所以导致2先弹出,并且执行到document.write(‘document.write("我是" + tmpStr)')调用tmpStr时,tmpStr并未定义,从而报错。

解决这个问题,可以利用HTML解析是解析完一个HTML标签,再执行下一个的原理,把代码拆分来实现:

<script type="text/javascript">//<![CDATA[
    document.write('<script type="text/javascript" src="test.js"><\/script>');
    //]]></script>
  <script type="text/javascript">//<![CDATA[
    document.write('<script type="text/javascript">');
    document.write('alert(2);')
    document.write('alert("我是" + tmpStr);');
    document.write('<\/script>');
    //]]></script>
  <script type="text/javascript">//<![CDATA[
    alert(3);
    //]]></script>

这样IE下和其他浏览器输出值的顺序都是一直的了:1、2、我是1、3。

三、如何改变Javascript在页面的执行顺序
1.利用onload

<script type="text/javascript">//<![CDATA[
window.onload = f;
function f(){alert(1);}
alert(2);
//]]></script>

输出值顺序是 2、1。

需要注意的是,如果存在多个winodws.onload的话,只有最有一个生效,解决这个办法是:

window.onload = function(){f();f1();f2();.....}

利用2级DOM事件类型
if(document.addEventListener){
window.addEventListener('load',f,false);
window.addEventListener('load',f1,false);
...
}else{
window.attachEvent('onload',f);
window.attachEvent('onload',f1);
...
}

2.IE中可以利用defer,defer作用是把代码加载下来,并不立即执行,等文档装载完毕之后再执行,有点类似window.onload,但是没有window.onload那样的局限性,可以重复使用,但是只在IE中有效,所以上面的例子可以修改成为
<script type="text/javascript">//<![CDATA[
document.write('<script type="text/javascript" src="test.js"><\/script>');
document.write('<script type="text/javascript" defer="defer">');
document.write('alert(2);')
document.write('alert("我是" + tmpStr);');
document.write('<\/script>');
//]]></script>
<script type="text/javascript">//<![CDATA[
alert(3);
//]]></script>

这样IE就不报错了,输出值的顺序变成:1、3、2、我是1

当HTML解析器遇到一个脚本,它必须按常规终止对文档的解析并等待脚本执行。为了解决这个问题HTML4标准定义了defer。通过defer来提示浏览器可以继续解析HTML文档,并延迟执行脚本。这种延迟在脚本从外部文件载入时非常有用,让浏览器不必等待外部文件全部载入之后才继续执行,能有效的提高性能。IE是目前唯一支持defer属性的浏览器,但IE并没有正确的实现了defer属性,因为延迟的脚本总是被延迟,直到文档结束,而不是只延迟到下一个非延迟的脚本。这意味着,IE中延迟的脚本的执行顺序相当混乱,并且不能定义任何后面非延迟脚本并须的函数和变量。在IE中所有的defer的脚本执行时间应该都是HTML文档树建立以后,window.onload之前。

3.利用Ajax。
因为xmlhttpRequest能判断外部文档加载的状态,所以能够改变代码的加载顺序

Javascript 相关文章推荐
前端开发过程中浏览器版本的两种判定方法
Oct 30 Javascript
node.js中的fs.lchownSync方法使用说明
Dec 16 Javascript
浅谈JavaScript的Polymer框架中的事件绑定
Jul 29 Javascript
jQuery实现可以控制图片旋转角度效果(附demo源码下载)
Jan 27 Javascript
JS动态给对象添加事件的简单方法
Jul 19 Javascript
使用bootstrap实现多窗口和拖动效果
Sep 22 Javascript
Vue的Class与Style绑定的方法
Sep 01 Javascript
Vue.js实现开发购物车功能的方法详解
Feb 22 Javascript
Angular使用ControlValueAccessor创建自定义表单控件
Mar 08 Javascript
vue2 拖动排序 vuedraggable组件的实现
Aug 08 Javascript
JS实现可视化音频效果的实例代码
Jan 16 Javascript
JavaScript实现单点登录的示例
Sep 23 Javascript
为什么要在引入的css或者js文件后面加参数的详细讲解
May 03 #Javascript
javascript两种function的定义介绍及区别说明
May 02 #Javascript
阻止子元素继承父元素事件具体思路及实现
May 02 #Javascript
jquery 触发a链接点击事件解决方案
May 02 #Javascript
jQuery弹性滑动导航菜单实现思路及代码
May 02 #Javascript
js通过地址栏给action传值(中文乱码全是问号)
May 02 #Javascript
如何使用jQuery来处理图片坏链具体实现步骤
May 02 #Javascript
You might like
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
php采用ajax数据提交post与post常见方法总结
2014/11/10 PHP
利用php生成验证码
2017/02/23 PHP
laravel + vue实现的数据统计绘图(今天、7天、30天数据)
2018/07/31 PHP
多引号嵌套的变量命名的问题
2014/05/09 Javascript
详解Angularjs filter过滤器
2016/02/06 Javascript
AngularJS入门教程之ng-checked 指令详解
2016/08/01 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
2016/09/19 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
2017/05/02 Javascript
使用Vue如何写一个双向数据绑定(面试常见)
2018/04/20 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
CountUp.js数字滚动插件使用方法详解
2019/10/17 Javascript
js实现随机圆与矩形功能
2020/10/29 Javascript
vue+iview使用树形控件的具体使用
2020/11/02 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
[58:46]OG vs NAVI 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
介绍Python中内置的itertools模块
2015/04/29 Python
搞笑的程序猿:看看你是哪种Python程序员
2015/06/12 Python
Python GUI Tkinter简单实现个性签名设计
2018/06/19 Python
浅谈Python traceback的优雅处理
2018/08/31 Python
Python 用matplotlib画以时间日期为x轴的图像
2019/08/06 Python
浅析python 通⽤爬⾍和聚焦爬⾍
2020/09/28 Python
Python读取pdf表格写入excel的方法
2021/01/22 Python
Python中Pyspider爬虫框架的基本使用详解
2021/01/27 Python
详解Sticky Footer 绝对底部的两种套路
2017/11/03 HTML / CSS
h5页面背景图很长要有滚动条滑动效果的实现
2021/01/27 HTML / CSS
沃达丰英国有限公司:Vodafone英国
2019/04/16 全球购物
.NET remoting中对象激活的两种方式
2015/06/08 面试题
最新创业融资计划书
2014/01/19 职场文书
艺术节主持词
2014/04/02 职场文书
教师考核评语
2014/04/28 职场文书
医院党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
优秀毕业生主要事迹材料
2015/11/04 职场文书
Python实现自动玩连连看的脚本分享
2022/04/04 Python