Js中对外部js文件的引用顺序直接影响到未定义的问题
javascript
1、在HTML中嵌入Javasript的方法
1.直接在Javascript代码放在标记对<script>和</script>之间,由<script />标记的src属性制定外部的js文件
2.放在事件处理程序中,好比:<p onclick="alert('我是由onclick事件执行的Javascript')">点击我</p>
做为URL的主体,这个URL使用特殊的Javascript:协议,好比:<a javascript:alert('我是由javascript:协议执行的javascript')">点击我</a>
3.利用javascript自己的document.write()方法写入新的javascript代码
4.利用Ajax异步获取javascript代码,而后执行
第3种和第4种方法写入的Javascript须要触发才能执行,因此除非特别设置,不然页面加载时不会执行。
2、Javascript在页面的执行顺序
页面上的Javascript代码是HTML文档的一部分,因此Javascript在页面装载时执行的顺序就是其引入标记<script />的出现顺序, <script />标记里面的或者经过src引入的外部JS,都是按照其语句出现的顺序执行,并且执行过程是文档装载的一部分。
每一个脚本定义的全局变量和函数,均可以被后面执行的脚本所调用。
变量的调用,必须是前面已经声明,不然获取的变量值是undefined。
java
<script type="text/javscrpt"> alert(tmp); //输出 undefined var tmp = 1; alert(tmp); //输出 1 </script>
同一段脚本,函数定义能够出如今函数调用的后面,可是若是是分别在两段代码,且函数调用在第一段代码中,则会报函数未定义错误。
浏览器
<script type="text/javscrpt"> aa(); //浏览器报错 </script>
<script type="text/javscrpt"> aa(); //输出 1 function aa(){alert(1);} /script>
document.write()会把输出写入到脚本文档所在的位置,浏览器解析完documemt.write()所在文档内容后,继续解析document.write()输出的内容,而后在继续解析HTML文档。(特殊符号没有处理,不然很难看...)
<script type="text/javascript">
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">
alert(3);
<script>
test.js的内容是:
var tmpStr = 1;
alert(tmpStr);
在Firefox和Opera中的弹出值的顺序是:一、二、我是一、3
在IE中弹出值的顺序是:二、一、3,同时浏览器报错:tmpStr未定义
缘由多是IE在document.write时,并未等待加载SRC中的Javascript代码完毕后,才执行下一行,因此致使2先弹出,而且执行到document.write(’document.write("我是" + tmpStr)’)调用tmpStr时,tmpStr并未定义,从而报错。
解决这个问题,能够利用HTML解析是解析完一个HTML标签,再执行下一个的原理,把代码拆分来实现:
<script type="text/javascript">
document.write('<script type="text/javascript" src="test.js"></script>);
</script>
<script type="text/javascript">
document.write('<script type="text/javascript">);
document.write('alert(2);')
document.write('alert("我是" + tmpStr);');
document.write('</script>);
</script>spa
<script type="text/javascript">
alert(3);
</script> code
这样IE下和其余浏览器输出值的顺序都是一直的了:一、二、我是一、3。
3、如何改变Javascript在页面的执行顺序
利用onload
<script type="text/javascript">
window.onload = f;
function f(){alert(1);}
alert(2);
</script>orm
输出值顺序是 二、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);
...
}
IE中能够利用defer,defer做用是把代码加载下来,并不当即执行,等文档装载完毕以后再执行,有点相似window.onload,可是没有window.onload那样的局限性,能够重复使用,可是只在IE中有效,因此上面的例子能够修改为为
<script type="text/javascript">
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">
alert(3);
</script>
这样IE就不报错了,输出值的顺序变成:一、三、二、我是1 当HTML解析器遇到一个脚本,它必须按常规终止对文档的解析并等待脚本执行。为了解决这个问题HTML4标准定义了defer。经过defer来提示浏览器能够继续解析HTML文档,并延迟执行脚本。这种延迟在脚本从外部文件载入时很是有用,让浏览器没必要等待外部文件所有载入以后才继续执行,能有效的提升性能。IE是目前惟一支持defer属性的浏览器,但IE并无正确的实现了defer属性,由于延迟的脚本老是被延迟,直到文档结束,而不是只延迟到下一个非延迟的脚本。这意味着,IE中延迟的脚本的执行顺序至关混乱,而且不能定义任何后面非延迟脚本并须的函数和变量。在IE中全部的defer的脚本执行时间应该都是HTML文档树创建之后,window.onload以前