HTML中的JavaScript
script标签
属性
- async
- defer
- charset:指定src的代码字符集
- crossorigin:跨域资源相关配置
- annoymous:表示不必设置凭证
- use-credentials:包含凭证
- integrity:资源的加密签名,验证资源的完整性,可以保证CDN(内容分发网络)的资源没有被篡改
- type:module表示ES6模块,可以使用import、export
使用方式
- 直接嵌入代码
- 代码被计算完成之前,页面的其他内容不会被加载,也不会被显示。
- 注意代码中不能包含
</script>
,会被误当成结束标签。可以使用转义符解决。
- 引入外部JavaScript文件
- 浏览器不会检查包含JavaScript文件的扩展名
- 标签内部的代码会被忽略
- 可以引入外部域的JavaScript文件,不受同源策略的影响,返回的内容仍受限制。
不管包含的是什么代码,浏览器都会按照<script>
在页面中出现的顺序依次解释它们,前提是它们没有使用defer和async属性。
放置位置
现代web应用程序通常将JavaScript引用放在<body>
元素中的页面内容后面,来缩短页面空白的时间。
推迟执行脚本
设置defer属性,相当于告诉浏览器立即下载,但延迟执行。它们会在浏览器解析到结束的</html>
标签后才会按顺序执行。
不过在实际当中,推迟执行的脚本不一定总会按顺序执行或者在DOMContentLoaded事件之前执行,因此最好只包含一个这样的脚本。
defer属性只对外部脚本文件有用,行内脚本的defer属性会被忽略,对于不兼容的浏览器,会按通常的做法来处理脚本,因此还是页面底部比较好。
异步执行脚本
设置async属性,与defer不同的是,标记为async的脚本并不保证能按照它们出现的次序执行。给脚本添加async属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改DOM。
异步脚本保证会在页面的load事件前执行,但可能会在DOMContentLoaded(参见第17章)之前或之后。
动态加载脚本
我们可以使用DOM API动态加载脚本,当然,在把HTMLElement元素添加到DOM且执行到这段代码之前不会发送请求。
默认情况下,以这种方式创建的<script>
元素是以异步方式加载的,相当于添加了async属性。但不是所有浏览器都支持async,如果要统一动态脚本的加载行为,可以把async属性设置为false,表明其为同步加载。
这种方式获取资源对于浏览器预加载器是不可见的,会严重影响他们在资源获取队列中的优先级。我们可以在文档头部显式的声明它们:
<link rel="preload" href="gibberish.js">
外部文件引用的优点
- 可维护性
- 如果代码分散在html文件中,维护困难,同时开发者可以独立于html编写js代码
- 可缓存
- 如果多个页面用到同个js文件,该文件只需要下载一次。页面加载更快。
- 适应未来
- HTTP2 server push
文档模式
混杂模式和标准模式,两者主要区别只体现在CSS渲染的内容方面,但对js也有一些关联影响。
后续又出现了准标准模式,但很少需要区分,与标准模式非常接近。
noscript标签
用于给不支持JavaScript的浏览器提供替代内容,针对早期浏览器不支持JavaScript的问题提供了优雅降级的处理方案。
- 浏览器不支持脚本
- 浏览器对脚本的支持被关闭
<noscript>
<p>This page requires a JavaScript-enabled browser.</p> </noscript>