「这是我参与2022首次更文挑战的第 6 天,活动详情查看:2022首次更文挑战」。
咸鱼计划之重红宝书第 3 篇~
在网页端,主导语言是HTML,想要把js引入网页,首先要解决的是HTML与js的关系。最早的时候,网景就把js通过脚本的方式插入HTML,并且最终形成了HTML规范。
Script元素
把js插入HTML的主要方法是使用<script>元素,目前<script>元素有以下几个可用的属性,注意其中有属性被废弃,也有属性因为不被大多数浏览器在乎而名存实亡:
-
src:可选。表示包含要执行的代码的外部文件。
-
async:可选。表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源活等待其他脚本加载。只对外部脚本文件有效,就是只有在使用src属性时才生效。
-
crossorigin:可选。配置相关请求的CORS(跨资源共享)设置。默认不使用CORS。crossorigin="anonymous"配置文件请求不必设置凭据标志。crossorigin="use-credentials"设置凭据标志,意味着出站请求会包含凭据。
-
integrity:可选。允许比对接到的资源和指定的加密签名以验证子资源完整性(SRI,Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性可以用于确保内容分发网络(CDN,Content Delivery Network)不会提供恶意内容。
-
type:可选。代替language,表示代码块中脚本语言的内容类型(也称MIME类型)。按照惯例,这个值始终都是"text/javascript",尽管"text/javascript"和"text/ecmascript"都已经废弃了。js文件的MIME类型通常是"application/x-javascript",不过给type属性的这个值有可能导致脚本被忽略。在非IE的浏览器中有效的其他值还有"application/javascript"和"application/ecmascript"。如果这个值是module,则代码会被当成ES6模块,而且只有这时候代码中才能出现import和export关键字。
-
defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。不过只有IE支持这个属性~
-
charset:可选。使用src属性指定的代码字符集。但是大多数浏览器都不在乎它的值,人微言轻的,不用在意~
-
language:废弃。
Script元素位置
long long ago,<script>元素是被放在<header>中的,但是这样做最大的缺点就是必须把所有的js代码都下载、解析和解释完成之后,才能开始渲染页面,因为页面的浏览器解析到body的起始标签才开始渲染。那么对于稍微大点的js来说,这个下载、解析和解释的过程就会比较缓慢,也就意味着用户要看到一段时间的空白页面,这个体验当然是不好的。
为了解决这个问题,只要把js的<script>元素放到body元素中的页面内容后面就可以了:
<body>
<div>页面</div>
<script src='./main.js'>
</body>
这样处理之后,js就不会阻塞页面的渲染,用户就能快点看到页面,用户体验up~
动态加载脚本
除了通过在HTML中添加<script>标签添加脚本之外,还可以通过js添加<script>而动态加载脚本。
let outer = document.createElement('script');
outer.src = './abc.js';
document.head.appendChild(outer);
这样创建的<script>默认是异步加载的,相当于添加了async属性,但是注意不是所有浏览器都支持async属性属性,所以可以再加一行outer.async=false来统一动态脚本的加载行为。
不过,这种方式获取的资源对浏览器预加载器是不可见的,甚至会严重影响它们在资源获取队列中的优先级。为了性能考虑,我们一般会需要让预加载器知道这些动态请求文件的存在,办法就是在文档头部显式声明它们:
<link rel="preload" href="abc.js">
XHTML
可扩展超文本标记语言,Extensible HyperText Markup Language。是HTML的XML包装版,已经退出历史舞台,你可能在某个祖传项目中会见到,稍作了解即可~
在XHTML中,type属性必须指定值为"text/javascript",HTML中不做限制。
总结
HTML中的js举足轻重,虽然看似有很多的灵活性,但其实很多用法都是约定俗成的,而这个约定的原因就是为了性能和维护度考虑。
- script尽量引入外部文件,原因有三:可维护性、缓存、适应未来。
- 不定义type。这么做主要是因为MIME类型并没有夸浏览器标准化。就是说,就算你写了,可是人家某个浏览器不认可,所以还是别写了吧。
- 现在所有浏览器都支持js,但是有部分禁用了js,这个时候可能导致你某些功能没法用而需要给用户一些提示,这个时候可以用元素。