【javascript】script标签的defer,async属性

    今天跟大家一起学习一下script标签的defer与async属性。

    1、defer

    很多程序员将引入外部js文件的script标签写在html文档的底部。这样做的目的是为了什么呢?

    首先我们知道用户代理在解析html文档的顺序是从上至下的,在解析过程中,如果遇到引入css文件的link标签或者是引入js文件的script标签。那么用户代理就会停止往下解析,而是先将需要引入的文件下载下来并运行。

    如果将引入js文件的script标签放在body标签的上面。那么用户代理将会先暂停解析html文档,而是将js文件下载下来并运行该脚本。

    如果引入的js文件中有对dom元素进行操作,而用户代理此时没有解析body标签中的内容。这就会导致程序无法获取到dom元素并对其进行操作,最后的结果当然是报错。现在大家明白为啥大部分coder喜欢将引入外部js文件的script标签放在文档底部了吧,就是为了避免发生这种错误。

    当然,如果你非要说:我骨骼精奇,我非要将此类script标签放在head标签中怎么办?有解决这种问题的方法吗?答案当然是有的,请往下看。

    解决方法一:使用$(func) 与 document.ready = func  或 window.onload = func 方法。

    在引入的js文件中将对页面初始化时要进行的dom操作放在以上三个方法体中,那么这部分代码将在用户代理将dom全部解析完毕之后执行,就避免了以上我们提到的问题出现。

    那么这三种方法有什么区别呢?

    首先 document.ready = func 是原生js提供的方法。在jQuery中对其进行的封装是 $(document).ready(func);而 $(func)是$(document).ready(func)的简化写法,相当于语法糖的作用。所以 document.ready = func , $(document).ready(func) , $(func)三种写法的作用是完全一样的,根据各自喜好选择使用即可。

    我们再来讲讲 document.ready = func 与 window.onload = func 的区别。 document.ready = func执行时机是在html文档中的dom结构全部解析完后执行。而window.onload = func 是在整个html文档解析完后执行。所以 document.ready 是比 window.onload 先执行的。

    解决方法二:我们今天的主角: defer属性。

    使用方法如下:

    【javascript】script标签的defer,async属性

    【javascript】script标签的defer,async属性

    控制台打印结构:

    【javascript】script标签的defer,async属性

    从控制台打印顺序我们能很直观的了解defer属性的作用。当一个script标签中加上了defer属性,那么当用户代理解析完整个html文档后才会执行该脚本文件。

    2、async

     使用方法:

    【javascript】script标签的defer,async属性

    首先我们在script标签上添加async属性,当用户代理解析到该script标签时,用户代理将再创建一条进程去运行该脚本程序,当前进程继续向下执行。我再跟大家讲二个具体的使用场景,我们应该就能更好的使用async属性了。

    场景一:实现一个网站访问量统计的功能,可以将该功能接口调用写在单独的js文件中,然后通过添加有async属性的script标签引入。当用户代理解析到该行script标签时,会另起一个进程,将用户信息传递给后台进行统计,不影响当前html文档的解析。

    场景二:实现一个广告推送功能,用户代理解析到该script标签时,用户代理另起一个线程,将用户信息传递到后台,后台通过对用户信息的分析,推送不同的广告信息到客户端。

    ok,今天的学习分享到此结束,3Q!

    

    

转载于:https://my.oschina.net/cc4zj/blog/1590415