script元素
script标签的作用就是将js插入到HTML
属性表示不同的场景
async
defer
src
type
crossorigin
charset
使用script标签的注意点
不要出现在字符串中出现 </script> , 浏览器会当成结束标签解析
解决方案 : 转义 <\/script>
script的标签位置
放在<head></head>标签中, 就意味着必须把js代码解析完成之后, 才开始渲染页面
执行到 <body></body> 标签时才开始渲染页面
此时会有一个问题存在 如果我script的标签有10000+那我的页面岂不是显示的很慢?
完美的做法 ------> script标签放在body标签的最后位置
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
...................
<script src="demo1.js"></script>
<script src="demo2.js"></script>
</body>
script 场景一 --- 推迟执行脚本 ( 仅限于script标签引入外部js文件 ) --- defer属性
script 标签 设置 defer 属性时, 被认为立即下载, 最后执行
最后两个脚本可能会在 DOMContentLoaded 事件前或后可能按顺序执行
如果你觉得这是个问题 ---- 那就推迟一个脚本
<head>
.....
<title>Document</title>
<script defer src="demo1.js"></script>
<script defer src="demo2.js"></script>
</head>
script 场景二 --- 异步执行脚本( 仅限于script标签引入外部js文件 ) --- async属性
script 标签 设置 async 属性时, 被认为立即下载不阻塞加载dom, 不保证执行顺序
设置 async 属性 告诉浏览器 你不必等我加载完或执行完再去加载页面和执行其他脚本
<script async src="demo1.js"></script> console.log(1)
<script defer src="demo2.js"></script> console.log(2)
执行结果 可能是 1 , 2 也可能是 2, 1
script 场景三 --- 动态加载脚本
实现原理 : createElement(' script ') 创建script元素 追加时默认 async 属性为 true
<body>
...................
<button>动态加载脚本</button>
<script>
const btn = document.getElementsByTagName('button')
btn[0].addEventListener('click', () => {
const script = document.createElement('script')
script.src = 'demo2.js'
document.head.appendChild(script)
})
</script>
</body>
弊端 (红宝书原话) : 这种方式动态加载资源对浏览器预加载器是不可见的 , 这会影响资源在获取队列中的优先级 , 可能会影响性能
解决方案 : 告诉浏览器我可能要动态的加载资源文件
<head>
...............
<script src="demo1.js"></script>
<link rel="preload" href="demo2.js">
</head>