HTML 中的 JavaScript
2.1 script元素
1.属性:
- async(异步):该立即开始下载脚本,但不能阻止其他页面动作——aysnc脚本会在后台加载,并在加载就绪时运行。DOM和脚本不会等待他们,他们也不会等待其他东西。async 脚本就是一个会在加载完成时执行的完全独立的脚本。以“加载优先”的顺序执行。只对外部脚本文件有效。
- defer(推迟):defer 特性告诉浏览器不要等待脚本。相反,浏览器将继续处理 HTML,构建 DOM。脚本会 “在后台” 下载,然后等 DOM 构建完成后,脚本才会执行。具有 defer 特性的脚本保持其相对顺序,即使后面的脚本加载完成了,也会等前面的脚本执行结束才会执行。只对外部脚本文件有效,支持h5的浏览器会忽略行内脚本的defer熟悉。
- charset(字符集):可选。使用 src 属性指定的代码字符集。这个属性很少使用,因为大多数浏览器不
在乎它的值。 - crossorigin(跨越):配置相关请求的CORS(跨源资源共享)设置。默认不使用CORS。
|属性值| 简介 |
| “” |anonymous| 请求中的 header 中的带上 Origin 属性 |
| use-credentials| 请求中的 header 中的带上 Origin 属性,同时会在跨域请求中带上 cookie 和其他的一些认证信息 | - integrity(正直):允许比对接收到的资源和指定的加密签名以验证子资源完整性
- src(源文件):可选。表示包含要执行的代码的外部文件,浏览器在解析这个资源时,会向 src 属性指定的路径发送一个 GET 请求,以取得相应资源,假定是一个 JavaScript 文件。这个初始的请求不受浏览器同源策略限制,但返回并被执行的 JavaScript 则受限制。当然,这个请求仍然受父页面 HTTP/HTTPS 协议的限制。
- type(类型):可选。代替 language,表示代码块中脚本语言的内容类型(也称 MIME 类型)
async与defer的区别:async,defer
2.1.1标签位置
之前放在必须放置在head标签里,这样会导致页面渲染延迟(只有解析到body标签才开始渲染),现在也可以放置到body后面了
2.1.2延迟执行的脚本
设置了defer属性的script元素,虽然包含在页面的head中,但它们会在浏览器解析到结束的html标签后才会执行。
对 defer 属性的支持是从 IE4、Firefox 3.5、Safari 5 和 Chrome 7 开始的。其他所有浏览器则会忽略这个属性,按照通常的做法来处理脚本。考虑到这一点,还是把要推迟执行的脚本放在页面底部比较好。
延迟执行的脚本都会在 DOMContentLoaded 事件之前执行
对于 XHTML 文档,指定 defer 属性时应该写成 defer=“defer”。
2.1.3异步执行的脚本
async 属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改 DOM。
异步脚本保证会在页面的 load 事件前执行,但可能会在 DOMContentLoaded之前或之后
对于 XHTML 文档,指定 async 属性时应该写成 async=“async”。
2.1.4动态加载的脚本
const srcipt = document.createElement('srcipt');
srcipt.src = "demo.js"
document.appendChild(srcipt)
默认情况下,以这种方式创建的script元素是以异步方式加载的,相当于添加了 async 属性。不过这样做可能会
有问题,因为所有浏览器都支持 createElement()方法,但不是所有浏览器都支持 async 属性。因此,如果要统一动态脚本的加载行为,可以明确将其设置为同步加载。
script.async = false;
以这种方式获取的浏览器预加载器是不可见的,这会严重影响它们在资源获取队列中的优先级,要想让预加载器知道这些
动态请求文件的存在,可以在文档头部显式声明它们:
<Link rel="preload" ref="demo.js">
2.1.5XHTML中的变化
可扩展超文本标记语言(XHTML,Extensible HyperText Markup Language)是将 HTML 作为 XML的应用重新包装的结果。与 HTML 不同,在 XHTML 中使用 JavaScript 必须指定 type 属性且值为"text/javascript"
xhtml会把所有的<解析成标签的开始,并且作为标签开始的小于号后面不能有空格,所以以下模块在xhtml中会有语法错误
<script type="text/javascript">
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
</script>
解决方法1:将所有的小于号换成<
解决方法2:把所有代码都包含到一个 CDATA 块中。CDATA 块表示文档中可以包含任意文本的区块,其内容不作为标签来解析
<script type="text/javascript"><![CDATA[
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
]]></script>
在兼容 XHTML 的浏览器中,这样能解决问题。但在不支持 CDATA 块的非 XHTML 兼容浏览器中则不行。为此,CDATA 标记必须使用 JavaScript 注释来抵消:
<script type="text/javascript">
//<![CDATA[
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
//]]>
</script>
2.1.6废弃的语法
使用这种格式,Mosaic 等浏览器就可以忽略
<script><!--
function sayHi(){
console.log("Hi!");
}
//--></script>
2.2 行内代码与外部文件
推荐使用外部js文件
- 可维护性。JavaScript 代码如果分散到很多 HTML 页面,会导致维护困难。而用一个目录保存
所有 JavaScript 文件,则更容易维护,这样开发者就可以独立于使用它们的 HTML 页面来编辑
代码。 - 缓存。浏览器会根据特定的设置缓存所有外部链接的 JavaScript 文件,这意味着如果两个页面都
用到同一个文件,则该文件只需下载一次。这最终意味着页面加载更快。 - 适应未来。通过把 JavaScript 放到外部文件中,就不必考虑用 XHTML 或前面提到的注释黑科技。
包含外部 JavaScript 文件的语法在 HTML 和 XHTML 中是一样的。
2.3 文档模式
最初的文档模式有两种:混杂模式(quirks mode)和标准模式(standards mode)。前者让 IE 像 IE5 一样(支持一些非标准的特性),后者让 IE 具有兼容标准的行为。随着浏览器的普遍实现,又出现了第三种文档模式:准标准模式(almost standards mode)。这种模式下的浏览器支持很多标准的特性,但是没有标准规定得那么严格。主要区别在于如何对待图片元素周围的空白(在表格中使用图片时最明显)
准标准模式与标准模式非常接近,很少需要区分。人们在说到“标准模式”时,可能指其中任何一
个。而对文档模式的检测(本书后面会讨论)也不会区分它们。本书后面所说的标准模式,指的就是除
混杂模式以外的模式。
2.4 nosrcipt元素
noscript元素可以包含任何可以出现在body中的 HTML 元素,script除外。在下列两种情况下,浏览器将显示包含在noscript中的内容:
- 浏览器不支持脚本;
- 浏览器对脚本的支持被关闭
2.5 本章小结
本章的重点可以总结如下。
- 要包含外部 JavaScript 文件,必须将 src 属性设置为要包含文件的 URL。文件可以跟网页在同一台服务器上,也可以位于完全不同的域。
- 所有script元素会依照它们在网页中出现的次序被解释。在不使用 defer 和 async 属性的情况下,包含在script元素中的代码必须严格按次序解释。
- 对不推迟执行的脚本,浏览器必须解释完位于script元素中的代码,然后才能继续渲染页面的剩余部分。为此,通常应该把script元素放到页面末尾,介于主内容之后及body标签之前。
- 可以使用 defer 属性把脚本推迟到文档渲染完毕后再执行。推迟的脚本原则上按照它们被列出的次序执行。
- 可以使用 async 属性表示脚本不需要等待其他脚本,同时也不阻塞文档渲染,即异步加载。异步脚本不能保证按照它们在页面中出现的次序执行。
- 通过使用元素,可以指定在浏览器不支持脚本时显示的内容。如果浏览器支持并启用脚本,则元素中的任何内容都不会被渲染。