您的位置:首页 > Web前端

HTML中<script>标签使用defer属性——即延迟脚本与load事件注册程序

2012-09-13 17:22 232 查看

前言

HTML中的<script>标签大家都是知道的,嗯,是的,最常见的标签了。这个标签有一个defer属性,本文就来探讨一下HTML中<script>标签的defer属性,不管应用、笔试或者面试时,希望我们都能很好的面对这个defer属性。这里谈谈HTML中<script>标签的defer属性延迟脚本与load事件注册程序执行的先后问题。当然此文是从全面理解defer属性入手分析的。

一、script标签defer属性定义

要理解一个元素的属性,当然最权威的就是了解其官方定义喽,因此,关于<script>标签的defer属性,就从其定义开始介绍喽。

<script>标签的defer属性表示脚本可以延迟到文档完全被解析和显示后再执行。只对外部脚本有效。且是一个可选的属性。

<script>标签有6个属性哦,defer属性是其中的一个。详细定义可以在互联网上查到呢。给个链接方便查询喽:http://www.w3school.com.cn/tags/att_script_defer.asp

关于<script>标签defer属性定义差不多就是这样描述的啦,要怎么理解红色字体给出的<script>标签defer属性的定义呢?相信理论结合实例是最好的理解方式呢。

二、script标签defer属性的理解

从定义中可以得出以下的信息喽:

该属性只应用于对外部js脚本的引用时。

是可以有可以没有的,当然,如果没有使用defer属性,就不会对外部脚本应用这个属性的功能喽,@_@~貌似是废话呢。

defer属性的功能是延迟脚本的执行,注意这里是执行哦,不是加载呢。

外部脚本延迟到什么时间执行呢?定义中给出的信息是文档完全被解析和显示后哦。

差不多就是读出这些信息吧,我们就来一个个的理解喽。

第1点和第2点都很明了啦,就不多说了,先分析第4点吧,就是defer属性要延迟外部js脚本的执行,那是要等到什么时候才开始执行外部脚本呢?定义中说是要等到文档完全被解析和执行后。文档完全被解析和执行后,何为文档完全被解析和执行后呢?关于HTML文档,首先要加载,然后浏览器解析HTML标签,然后渲染,加载过程中遇到脚本则执行脚本,此时的脚本当然是没有被延迟执行喽。我们知道浏览器在对HTML文档的处理过程中,有一个默认的原则是“自上而下,自左而右”,相信关于这个原则大家是没有什么疑问的。由此就可以解释文档完全被解析和显示后是什么含义:也就是说喽,浏览器处理一个HTML文档,是自上而下自左而右地加载,边加载边解析(解析就是将HTML标签语言解释成相应的显示效果喽),最后页面完全被显示出来后,执行被延迟的脚本。说了这么多,文档完全被解析和显示后 可以认为是文档被加载,解析显示后这个时间点。

这些都没有什么疑问,但是我们给load事件注册事件处理程序,load事件处理程序触发执行的时间也是页面完全加载后执行的呢。因为load事件的触发事件就是页面完全加载完毕喽。那么此时HTML文档中<script>标签中使用了defer属性来延迟执行脚本,延迟执行的脚本执行事件也是页面加载解析完毕后呢,那这两个中的代码谁先执行呢。通过下面的代码可以验证:

<html>
<head>
<script type="text/javascript" src="test.js" defer="defer"></script>
</head>
<body>

....

<script type="text/javascript">
window.onload = function(){
alert("A");
}
</script>
</body>
</html>


以上代码中“test.js”中的代码是“alert("B");”,在火狐和IE9下测试的结果是先弹出“B”,后弹出“A”。这就证明了:当页面中有load事件处理程序,又有defer延迟脚本时,首先执行的是defer延迟脚本。也就是说,页面加载解析完毕后,立即执行defer延迟脚本,然后再执行load事件注册程序。

原因分析:谈一下自己的想法吧,首先先介绍完defer属性的理解,上面只是介绍了从定义中得出的4个信息的第4个点,第3点还没有说呢。defer属性的功能是延迟脚本的执行,但是并没有延迟脚本的加载,当浏览器解析到:

<script type="text/javascript" src="test.js" defer="defer"></script>


这段代码的时候,执行的动作是:立即加载,延迟执行。也就是说浏览器执行到这段代码的时候,已经将这段代码加载完毕,只是延迟执行而已。那么现在解释下为什么defer延迟脚本会早于load事件注册程序执行喽,因为defer脚本程序已经加载过,是属于页面中的一部分喽,而load事件指的是页面完全加载完毕才会触发的哦。希望这样能好理解些。

三、关于HTML中<script>标签的defer属性的补充

当页面脚本中出现:

<script type="text/javascript" defer="defer" src="example1.js"></script>
<script type="text/javascript" defer="defer" src="example2.js"></script>


时:HTML5规范要求脚本按照他们出现的先后顺序执行,因此第一个延迟执行脚本会先于第二个延迟执行脚本执行,并且需要注意的是这两个脚本会先于DOMContentLoaded事件执行,也就是load事件喽。这是HTML5中的规范。现在的执行情况是,延迟执行脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件执行触发前执行。HTML5还规范了defer属性只适用于外部脚本文件。IE4~IE7还支持对嵌入脚本的defer属性。IE8之后是支持HTML5规范的行为的。

掌握一个知识在于应用,在于表达,做到确实不易呀。欢迎指正~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: