js放在head中,只有他被调用的时候才去执行
js放在body中,在html加载的时候执行,会阻碍html的解析
一般有两种放置方式:
js放置在head标签中
js放置在body标签的最下面
浏览器在解析html的时候,如果遇到没有属性标签的script标签
就会暂停html的解析,
去发送网络请求去请求js文件的代码
让js引擎去执行这个js文件的代码
当js执行完之后,就会继续解析html
async 表示异步
当浏览器遇到带有 async 属性的 script 时
1,去请求该脚本的网络请求,但是是异步的,不会阻塞html
2,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器会暂停解析。
3,先让 JS 引擎执行代码,执行完毕后再进行解析
4,如果在 JS 脚本请求回来之前,HTML 已经解析完毕了,那就啥事没有,立即执行 JS 代码。
由上方可知async是不可控的
因为执行时间不确定,你如果在异步 JS 脚本中获取某个 DOM 元素,有可能获取到也有可能获取不到。
如果存在多个 async 的时候,它们之间的执行顺序也不确定,完全依赖于网络传输结果,谁先到执行谁。
defer 也表示异步 也有延迟的意思
当浏览器遇到带有 defer 属性的 script 时
1,获取该脚本的网络请求也是异步的,不会阻塞浏览器解析 HTML
2,一旦网络请求回来之后
3,如果此时 HTML 还没有解析完,浏览器不会暂停解析并执行 JS 代码,而是等待 HTML 解析完毕再执行 JS 代码。
如果存在多个 defer script 标签,浏览器(IE9及以下除外)会保证它们按照在 HTML 中出现的顺序执行,不会破坏 JS 脚本之间的依赖关系。
具有defer属性的script标签在HTML文档解析完毕后,DOMContentLoaded事件调用前执行。