HTML 中的 JavaScript
小结
1. script 元素有哪些属性?
async、defer、type、src、crossorigin、integrity
2. noscript
当浏览器不支持脚本或禁用脚本时,noscript 元素会显示出来
script
<script>
元素有以下属性:
- async:表示立即下载脚本,但不妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本,只对外部脚本文件有效
- defer:表示脚本可以延迟到文档完全被解析和显示之后再执行,只对外部脚本文件有效
- src:表示包含要执行代码的外部文件
- type:表示代码块中脚本语言的内容类型(MIME 类型),如果这个值是 module,则代码会被当成 ES6 模块,而且只有这时候代码中才能出现 import 和 export 关键字
- crossorigin:配置相关请求的 CORS(跨源资源共享)设置。默认不使用 CORS,也就是说,如果请求的资源不是同源的,那么将会忽略这个属性。如果设置了这个属性,那么请求会包含 Origin 头部信息,如果服务器认为这个请求是合法的,那么响应会包含 Access-Control-Allow-Origin 头部信息。这个属性的可用值如下:
- anonymous:发送请求时不会提供凭据信息(比如 cookie 等),也就是说,不会把当前域的 cookie 发送给目标请求
- use-credentials:发送请求时会提供凭据信息(比如 cookie 等),也就是说,会把当前域的 cookie 发送给目标请求
- integrity:允许比对接收到的资源和指定的加密签名以验证子资源完整性(SRI,Subresource Integrity)。如果接受到的资源与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性用于确保内容分发网络(CDN,Content Delivery Network)不会提供恶意内容
使用 <script>
的方式有两种:
- 直接在页面中嵌入行内 JavaScript 代码
<script>
function sayScript() {
// 出现字符串 </script> 时,需要转义
console.log('<\/script>')
}
</script>
- 通过 src 属性包含外部 JavaScript 文件
注:使用了 src 属性的 <script>
元素不应该在其 <script>
和 </script>
标签之间再包含额外的 JavaScript 代码,否则会忽略这些额外的代码
标签位置
- 放在页面的
<head>
元素中 - 放在页面的
<body>
元素中的页面内容后面
推迟执行脚本
在 <script>
元素中设置 defer 属性(只适用于外部脚本),告诉浏览器立即下载,但延迟执行(解析到 </html>
后)
HTML5 规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于 DOMContentLoaded 事件执行。但是延迟脚本不一定会按照顺序执行,也不一定会在 DOMContentLoaded 事件触发前执行,因此最好只包含一个延迟脚本
异步执行脚本
在 <script>
元素中设置 async 属性(只适用于外部脚本),告诉浏览器立即下载,与 defer 的区别是,异步脚本不保证按照它们的先后顺序执行
给脚本添加 async 属性的目的是告诉浏览器,不必等待其他脚本,也不必阻塞文档呈现,立即下载并执行脚本。从这个意义上讲,标记为 async 的脚本不应该在加载期间修改 DOM。异步脚本一定会在页面的 load 事件前执行,但可能会在 DOMContentLoaded 事件触发之前或之后执行
动态加载脚本
通过向 DOM 中动态添加 <script>
元素加载指定的脚本
const script = document.createElement('script')
script.src = 'gibberish.js'
document.head.appendChild(script)
默认情况下,动态添加的脚本是异步执行的(相当于 async 为 true)
因为所有浏览器都支持 createElement() 方法,但不是所有浏览器都支持 async 属性,因此如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:
const script = document.createElement('script')
script.src = 'gibberish.js'
script.async = false
document.head.appendChild(script)
以这种方式获取的资源对浏览器预加载器是不可见的,严重影响它们在资源获取队列中的优先级,可能会影响性能
要想让预加载器知道这些动态请求文件的存在,可以在文档头部显示生声明它们:
<link rel="preload" href="gibberish.js" />
noscript
<noscript>
元素可以包含任何可以出现在 <body>
元素中的 HTML 元素,它的作用是提供替代内容,只有以下情况下才会显示:
- 浏览器不支持脚本
- 浏览器对脚本的支持被关闭