【精读笔记】JavaScript高级程序设计 第2章 HTML中的JavaScript

在这里插入图片描述

第二章 HTML中的JavaScript

2.1

将JavaScript插入HTML的主要方式是使用<script>元素。<script>元素有以下八个属性。

  • async:可选。表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或者等待其他脚本加载。只对外部脚本文件有效
  • charset:可选。使用src属性指定的代码字符集。少用。
  • crossorigin:可选。配置相关请求的CORS(跨资源共享)设置。默认不使用CORS。
  • defer:可选。表示脚本可以延迟到文档完全被解析和显示置后再执行只对外部脚本文件有效
  • integrity:可选。允许比对接受到的资源和指定的加密签名以验证子资源完整性。如果接受到的资源的签名与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性可以用于确保内容分发网络不会提供恶意内容
  • language:废弃。最初用于表示代码块中的脚本语言。大多数浏览器都会忽略这个属性,不应该再使用它。
  • src:可选。表示包含要执行的代码块的外部文件。
  • type:可选。代替language,表示代码块中脚本语言的内容类型。按照惯例,这个值始终都是text/javascript

​ 使用<script>的方式有两种:通过它直接在网页中嵌入JavaScript代码,以及通过它在网页中包含外部JavaScript文件

​ 包含在<script>内的代码会被从上到下解释。在<script>元素中的代码被计算完成之前,页面的其余内容不会被加载,也不会被显示。

​ 要包含外部文件中的JavaScript,就必须使用src属性。这个属性的值是一个URL,指向包含JavaScript代码的文件。比如

<script src="example.js"></script>

与解释行内JavaScript一样,在解释外部JavaScript文件时,页面也会阻塞(阻塞事件也包含下载文件的时间)。在XHTML文档中,可以忽略结束标签,比如:

<script src="example.js /">

​ 注意,按照惯例,外部JavaScript文件的扩展名是.js。这不是必须的,因为浏览器不会检查所包含JavaScript文件的扩展名。这就为使用服务器端脚本语言动态生成JavaScript代码,或者在浏览器中将JavaScript扩展语言(比如TypeScript,或React的JSX)转译为JavaScript提供了可能性。不过服务器经常会根据文件扩展来确定相应的正确MIME类型。如果不打算使用.js扩展名,一定要确保服务器能返回正确的MIME类型。

<script>元素的一个最为强大、同时也备受争议的特性是它可以包含来自外部域的JavaScript文件。跟<img>元素很像,<script>元素的src属性可以是一个完整的URL,而且这个URL指向的资源可以跟包含它的HTML页面不在同一个域中,比如这个例子:

script src="http://www.somewhere.com/afile.js"></script>

​ 浏览器在解析这个资源时,会向src属性指定的路径发送一个GET请求,以取得相应资源,假定是一个JavaScript文件。这个初始的请求不受浏览器同源策略限制,但返回并被执行的JavaScript则受限制。这个个请求仍然受父页面HTTP/HTTPS协议的限制。

​ 来自外部域的代码会被当成加载它的页面的一部分来加载和解释。这个能力可以让我们通过不同的域分发JavaScript。不过,引用了放在别人服务器上的JavaScript文件时要格外小心,因为恶意的程序员随时可能替换这个文件。在包含外部域的JavaScript文件时,要确保该域是自己所有的,或者该域是一个可信的来源<script>标签的integrity属性是防范这种问题的一个武器,但这个属性也不是所有浏览器都支持。

​ 不管包含的是什么代码,浏览器都会按照<script>在页面中出现的顺序依次解释它们,前提是它们没有使用defer和async属性。

2.1.1 标签占位符

​ 过去,所有<script>元素都被放在页面的<head>标签内。这种做法的主要目的是把外部的CSS和JavaScript文件都几种放到一起。如:

<!DOCTYPE html>
<html>
  <head>
  <title>Example HTML Page</title>
  <script src="example1.js"></script>  //放置于<head>标签中
  <script src="example2.js"></script>
  </head>
  <body>
  <!--这里是页面内容-->
  </body>
</html>

​ 不过,把所有JavaScript文件都放在<head>里,也就意味着必须把所有JavaScript代码都下载、解析和解释完成后,才能开始渲染页面(页面在浏览器解析到<body>的起始标签时开始渲染)。对于需要很多JavaScript的页面,这会导致页面渲染的明显延迟,在此期间浏览器窗口完全空白。为解决这个问题,现代Web应用程序通常将所有JavaScript引用放在<body>元素中的页面内容后面,如下面的例子所示:

<!DOCTYPE html>
<html>
  <head>
  <title>Example HTML Page</title>
  </head>
  <body>
  <!--这里是页面内容-->
  <script src="example1.js"></script>   
  <script src="example2.js"></script>   //放置于<body>中,页面会在处理JavaScript代码之前完全渲染页面。用户会感觉页面加载更快了,因为浏览器显示空白页面的时间短了。
  </body>
</html>

2.1.2 推迟执行的脚本

​ HTML 4.01为<script>元素定义了一个叫defer的属性。这个属性表示脚本在执行的时候不会改变页面的结构。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行defer属性只对外部脚本才有效

<!DOCTYPE html>
<html>
  <head>
  <title>Example HTML Page</title>
  <script defer src="example1.js"></script>   //立即下载,但延迟执行
  <script defer src="example2.js"></script>   //虽然包含在页面的<head>中,但它们会在浏览器解析到结束的</html>标签后才会执行
  </head>
  <body>
  <!--这里是页面内容-->
  </body>
</html>

2.1.3 异步执行的脚本

HTML5为<script>元素定义了async属性。从改变脚本处理方式上看,async属性与defer类似。当然,它们两者也都只适用于外部脚本,都会告诉浏览器立即开始下载。不过,与defer不同的是,标记为async的脚本并不保证能按照它们出现的次序执行,比如上个例子中,examle2.js可能比第一个脚本先执行。重点在于它们之间没有依赖关系。给脚本添加async属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本

2.1.4 动态加载脚本

​ 除了<script>标签,还有其他方式可以加载脚本。因为JavaScript可以使用DOM API,所以通过向DOM中动态添加script元素同样可以加载指定的脚本。只要创建一个script元素并将其添加到DOM即可。

2.1.5 XHTML中的变化

可扩展超文本标记语言(XHTML,Extensible HyperText Markup Language)是将HTML作为XML的应用重新包装的结果。

2.2 行内代码与外部文件

​ 通常认为最佳实践是尽可能将JavaScript代码放在外部文件中。不过这个最佳实践并不是明确的强制性规则。推荐使用外部文件的理由如下。

  1. 可维护性 JavaScript代码如果分散到很多HTML页面,会导致维护困难。而用一个目录保存所有JavaScript文件,则更容易维护,这样开发者就可以独立于使用它们的HTML页面来编辑代码。
  2. 缓存 浏览器会根据特定的设置缓存所有外部链接的JavaScript文件,这意味着如果两个页面都用到同一个文件,则该文件只需下载一次。这最终意味着页面加载更快
  3. 适应未来 通过把JavaScript放到外部文件中,就不必考虑用XHTML或前面提到的注释黑科技。包含外部JavaScript文件的语法在HTML和XHTML中是一样的。

2.3 文档模式

​ IE5.5发明了文档模式的概念,即可以使用doctype切换文档模式

2.4 元素

针对早期浏览器不支持JavaScript的问题,需要一个页面优雅降级的处理方案。最终,<noscript>元素出现,被用于给不支持JavaScript的浏览器提供替代内容

2.5 小结

​ JavaScript是通过<script>元素插入到HTML页面中的。

  • **要包含外部JavaScript文件,必须将src属性设置为要包含文件的URL。**文件可以跟网页在同一台服务器上,也可以位于完全不同的域。
  • **所有<script>元素会依照它们在网页中出现的次序被解释。**在不使用defer和async属性的情况下,包含在<script>元素中的代码必须严格按次序解释。
  • 对不推迟执行的脚本,浏览器必须解释完位于<script>元素中的代码,然后才能继续渲染页面的剩余部分。为此,通常应该把<script>元素放到页面末尾,介于主内容之后及</body>标签之前
  • 可以使用defer属性把脚本推迟到文档渲染完毕后再执行。推迟的脚本原则上按照它们被列出的次序执行。
  • 可以使用async属性表示脚本不需要等待其他脚本,同时也不阻塞文档渲染,即异步加载。异步脚本不能保证按照它们在页面中出现的次序执行。
  • 通过使用<noscript>元素,可以指定在浏览器不支持脚本时显示的内容。如果浏览器支持并启用脚本,则<noscript>元素中的任何内容都不会被渲染。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值