script标签的那些事
1.浏览器对script标签的解析
我们常常听到,script要把它放到html的最后面,为什么呢?就放在head标签哪里可以吗?
答案是,可以放,但是最好不要放,除非加上一些特性.原因请听下面的分析.
假设index.html里面有这样的一段代码
<script src='a.js'></script> -------1-------
<script>
var a = 'hello world' -------2-------
console.log(a)
</script>
<script src='b.js'></script> -------3-------
浏览器解析到script标签,会并行下载a.js和b.js,然后开始从上往下执行1,2,3模块,在下载和执行js期间会阻塞浏览器往下解析,当1,2,3模块执行完以后,浏览器才会继续向下解析.如果在执行script标签期间有耗时的任务存在,那么浏览器白屏的时间会较长,所以,最好把script标签放在html的后面,避免阻塞页面的解析.
2.defer属性
仅适用于外链,规定脚本延迟执行,不阻塞页面.设置了该属性的script标签,会等到html解析完,DOMContentLoaded才执行,会按照出现的顺序执行.
3.async属性
仅适用于外链,规定脚本异步执行.下载不会阻塞页面解析,下载完以后执行,此时如果页面没有解析完,会阻塞页面解析.执行没有先后顺序,下载完以后就执行.
4.type属性为module(天生具有defer属性的特征,即DOMContentLoaded发生才会执行)
相比传统script,<script type="module"></script>将被当作一个JavaScript模块对待,被称为module script。这个属性支持es6的导入和导出(import,export)
<script type='module'>
var x = 10
</script>
<script>
console.log(x) //报错,x未定义
</script>
5.script与innerHTML
如何在网页中显示script标签,但是不执行?
利用元素的innerHTML属性,把script标签设为它的值,例如:
javascript document.body.innerHTML= '<script>alerr('不执行')</script>'
为什么这里script标签的内容不被执行?因为javascript在解析时,把'<'转为<,把'>'转为>所以执行脚本时,script里面的内容不会被执行.当浏览器渲染内容时,<,渲染成<,>渲染成>.
6.一张图概括script标签的加载和执行顺序