一般script标签会被放在头部或尾部,头部就是head标签里,尾部就是body里,也有放在body闭合标签之后。
1、script标签放在head标签内部
<head><title>获取DOM元素</title><script>var myElement = document.getElementById("atag");console.log(myElement);</script></head><body><div id="atag"><p>一个标签</p></div></body>
打印结果:
当script标签放在head标签里时,浏览器解析HTML,解析到script标签时,会先下载完所有script,再往下解析其他的HTML。在浏览器下载js时,是不能多个js一起下载的,且浏览器下载js时,会阻塞解析其他的HTML。因此,将script标签放在头部,会使网页内容呈现滞后,用户体验差。
2、script标签放在body标签内部
<body><div id="atag"><p>一个标签</p></div><script>var myElement = document.getElementById("atag");console.log(myElement);</script></body>
将script标签放在body尾部,浏览器会先解析完整个HTML页面,再下载js,这样的话,如果js执行出错了,最起码页面中的元素还可以加载出来,因为DOM文档是从上往下的顺序执行的。 但是对于一些高度依赖于js的网页,这样就会显得很慢。
3、script标签放在body闭标签之后
<body><div id="atag"><p>一个标签</p></div></body><script>var myElement = document.getElementById("atag");console.log(myElement);</script>
虽然放在body闭合标签之前和之后的打印结果是一样的,但是从HTML 2.0起放在body闭标签之后
就是不合标准的。之所以浏览器不会报错,是因为如果在body标签之后
再出现script或任何元素的开始标签,都是prase error
(语法错误),浏览器会忽略之前的</body>
,即视作仍旧在body内部,所以实际效果和写在body闭合标签之前
是没有区别的。
怎样实现边解析页面边下载js呢?
async
和defer
async
async的设置,会使得script脚本异步的加载并在允许的情况下执行,但是并不会按照在script在页面中的顺序来执行,而是谁先加载完谁执行。
<script async src="/script01.js"></script><script async src="/script02.js"></script>
如果script01.js较大,下载慢,则会导致script02.js可能先于script01.js执行。
defer
defer的设置,会是浏览器异步的下载该文件并且不会影响到DOM的渲染,如果有多个设置了defer的script标签存在,则会按照顺序执行所有的script,即先下载script01.js,再下载script02.js