script标签的产生
为了解决JavaScript既能与html页面共存,又不影响页面的显示效果,为web增加同意的脚本支持
script标签的属性
1. type属性
默认值为type=‘text/javascript’
type是代替已经废弃的language属性,表示代码使用的脚本语言的内容类型
2. src属性(指定外部脚本文件的URL)
如果要在网站的多个页面上运行相同的JavaScript,则应该创建外部JavaScript文件,而不是重复编写相同的脚本。使用.js扩展名保存脚本文件,然后使用
- 绝对URL-指向另一个网站(如:src=“http://www.example.com/example.js”)(这样可能会出现跨域脚本攻击)
- 相对URL-指向与当前域名一致的文件(如:src="/scripts/example.js")
<html>
<head></head>
<body></body>
<script src="/index.js">
console.log('index.js')
</script>
</html>
上述代码会不会在控制台输出index.js字符???
不能,因为当使用了src外部资源时,浏览器就不会解析执行
3. defer属性
该属性是html4.01为< script >标签放在< head >中定义的,在执行的时候不会影响到页面构造
<html>
<head>
<script src="/index.js" defer="defer"></script> <!--目的是告诉浏览器,可以立即下载js,但是会延迟执行代码 -->
</head>
<body>
<div id="root"></div>
</body>
</html>
<html>
<head>
<script src="/index1.js" defer="defer"></script>
<script src="/index2.js" defer="defer"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
注:HTML5规范要求脚本按照他们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件执行。而在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,因此最好只包含一个延迟脚本
4. async属性
async属性与defer类似。async只适合外部脚本文件,告诉浏览器立即下载文件,但与defer不同的是async并不保证按照他们出现的先后顺序执行;指定async属性的目的是不让页面等待两个脚本下载执行,从而异步加载页面其他内容
<html>
<head>
<script src="/index1.js" async></script>
<script src="/index2.js" async></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
上述代码不确定先执行哪个,因此要保证index.js不依赖于index1.js
async和defer的区别:
async是乱序的,而defer是顺序执行的,一个普通的 script 标签的加载和解析都是同步的,会阻塞dom的渲染,把script标签放在body的底部,原因之一是为了防止加载资源而导致长时间的白屏,另一个原因是js可能会阻塞dom操作,所以要在dom全部渲染完成之后再执行
5. language属性(已弃用)
6. charset属性
表示通过src熟悉指定的代码的字符集,由于大多数浏览器会忽略它的值,因此很少使用
script的使用
1. 嵌入使用
包含 < script >的代码将会从上到下依次解析,再script元素内部的所有代码解析完之前,页面中其余的内容都不会被浏览器加载或者显示
<html>
<head>
</head>
<body>
<div id="root"></div>
</body>
<script>
function sayHi(){
cosole.log("</script>")
} // 在浏览器加载时会出现一个错误
</script>
</html>
2. 外部引入
这种引入方式和嵌入的加载顺序一样,但是多了一步下载流程,同时有很多优缺点
优点:
- 可以统一集中的管理开发js
- 相对于嵌入式对html的整洁性有很大的提高
- 有利于分离开发
<html>
<head>
<script src="/index1.js" async></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
缺点:
如果index1.js代码解析较慢的话,就会出现一个空白页面;
如果index1.js解析很快的话,由于index1.js操作了某个dom 其实,是无效的
< script >标签的async和defer属性可以解决上面的问题,但是也是有局限性的
- async能够保证不立即执行代码,但是无法保证两个外链代码的执行顺序
- defer虽然可以保证执行顺序但是一般浏览器并不是这样执行的
<html>
<head>
<script src="/index1.js" async></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
因此最好的解决方案就是将script标签放在body底部