转行学前端的第 24 天 : 在 HTML 中 使用 Javasciript

977 阅读12分钟

我是小又又,住在武汉,做了两年新媒体,准备用 6 个月时间转行前端。

今日学习目标


昨天基于一些页面搜索,学习了《JavaScirpt 高级程序设计》(第三版) 1.2 章节中的 JavaScript 实现,今天主要是基于搜索来学习第 2 章节中的 JavaScript 嵌入页面使用,又是适合学习的一天,加油,小又又!!!!


今日学习概要


把 JavaScript 插入到 HTML 页面中主要是使用 <scirpt> 标签

  • <script> 标签使用说明
  • 外部脚本
  • 禁用 Javascript 的场景

<script> 标签

基础说明

内容分类 元数据内容, 流式元素, 短语元素
可用内容 动态脚本,如 text/javascript.
标签省略 不允许,开始标签和结束标签都不能省略。
可用父元素 一些元素可以接受元数据内容, 或则是一些元素可以接受短语元素。
允许的 ARIA 角色
DOM接口 HTMLScriptElement


属性说明


<script> 也支持 通用的全局属性

属性名 具体说明
asyncHTML5 新增 该布尔属性指示浏览器是否在允许的情况下异步执行该脚本。该属性对于内联脚本无作用 (即没有src属性的脚本)。
关于浏览器支持请参见浏览器兼容性。另可参见文章asm.js的异步脚本
crossorigin 那些没有通过标准CORS检查的正常script 元素传递最少的信息到 window.onerror
可以使用本属性来使那些将静态资源放在另外一个域名的站点打印错误信息。参考 CORS 设置属性了解对有效参数的更具描述性的解释。
defer 这个布尔属性被设定用来通知浏览器该脚本将在文档完成解析后,触发 [DOMContentLoaded](https://developer.mozilla.org/zh-CN/docs/Web/Reference/Events/DOMContentLoaded) 事件前执行。
如果缺少 src 属性(即内嵌脚本),该属性不应被使用,因为这种情况下它不起作用。对动态嵌入的脚本使用 async=false 来达到类似的效果。
integrity 包含用户代理可用于验证已提取资源是否已无意外操作的内联元数据。参见 Subresource Integrity
nomodule 这个布尔属性被设置来标明这个脚本在支持 ES2015 modules 的浏览器中不执行。 
— 实际上,这可用于在不支持模块化JavaScript的旧浏览器中提供回退脚本。
src 这个属性定义引用外部脚本的URI,这可以用来代替直接在文档中嵌入脚本。
指定了 src 属性的script元素标签内不应该再有嵌入的脚本。
type 该属性定义script元素包含或src引用的脚本语言。属性的值为MIME类型; 支持的MIME类型包括text/javascripttext/ecmascriptapplication/javascript, 和application/ecmascript。如果没有定义这个属性,脚本会被视作JavaScript。

如果MIME类型不是JavaScript类型(上述支持的类型),则该元素所包含的内容会被当作数据块而不会被浏览器执行。
如果type属性为module,代码会被当作JavaScript模块 。请参见ES6 in Depth: Modules

在Firefox中可以通过定义type=application/javascript;version=1.8来使用如let声明这类的JS高版本中的先进特性。 但请注意这是个非标准功能,其他浏览器,特别是基于Chrome的浏览器可能会不支持。

关于如何引入特殊编程语言,请参见这篇文章
text 和 textContent 属性类似,本属性用于设置元素的文本内容。但和 textContent  不一样的是,本属性在节点插入到DOM之后,此属性被解析为可执行代码。
nonce 用于在脚本src内容安全策略中列出内联脚本的加密nonce(一次使用的数字)。

服务器每次传输策略时都必须生成唯一的nonce值。提供一个不能被猜测为绕过资源策略的nonce是非常关键的,否则它是微不足道的。
referrerpolicy 指示在获取脚本或脚本获取的资源时要发送的引用:

no-referrer:不会发送引用头。
no-referrer-when-downgrade(默认):引用头不会发送到没有 TLS(HTTPS)的源。
origin:发送的引用将限于引用页的来源:其方案、主机和端口。
origin-when-cross-origin:发送到其他源的引用将限于方案、主机和端口。在同一原点上的导航仍将包括路径。
same-origin:将为同一来源发送推荐人,但跨来源请求将不包含推荐人信息。
strict-origin:仅当协议安全级别保持不变(如 HTTPS → HTTPS )时,将文档的来源作为引用发送,但不要将其发送到不太安全的目的地(如 HTTPS → HTTP)。
strict-origin-when-cross-origin:执行相同源请求时发送完整的 URL,但仅在协议安全级别保持不变(例如 HTTPS → HTTPS )时发送源,并且不向不太安全的目标(例如 HTTPS → HTTP )发送头。
unsafe-url:引用程序将包括源和路径(但不包括片段、密码或用户名)。此值是不安全的,因为它将源和路径从受 TLS 保护的资源泄漏到不安全的源。

注意:空字符串值('')是默认值,如果不支持 refererpolicy,则为回退值。

如果在 <script> 元素上未显式指定 refererrepolicy,则它将采用更高级别的 referer 策略,即在整个文档或域上设置一个。如果更高级别的策略不可用,则在降级时,空字符串被视为等同于没有引用。


基础案例


在页面中直接嵌入 javascript 脚本,需要为 script 设置 type 属性,然后将代码直接放到 标签内部就可以啦~~~

<script type="text/javascript">
  function sayHi(){
    alert("Hi ,小又又~~~~~");
  }
 
</script>

注意事项

<script> 标签的位置


注意这个位置,推荐放置到 结束标签前,这样,在解析包含的 JavaScript 代码前,页面的内容将完全呈现在浏览器中。

而用户也会因为浏览器窗口显示空白页面的时间缩短了,而觉得打开页面变快了~~~~

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
  <title>小又又 学习 前端 </title>
  <meta name="keywords" content="小又又,学前端">
  <meta name="description" content="小又又的描述测试~~~~~~">
  <meta name="author" content="小又又">
</head>
<body>
  你好, 小又又~~~

  <script type="text/javascript">
    function sayHi(){
      alert("你好, 小又又~~~");
    }
   
</script>
</body>
</html>

</scirpt> 字符串


在使用 <script> 嵌入 JavaScript 代码时,记住不要在代码中的任何地方出现 "" 字符串。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
  <title>小又又 学习 前端 </title>
  <meta name="keywords" content="小又又,学前端">
  <meta name="description" content="小又又的描述测试~~~~~~">
  <meta name="author" content="小又又">
  <script defer="defer" src="example1.js"></script>
  <script defer="defer" src="example2.js"></script>
</head>
<body>
  你好, 小又又~~~
  <script type="text/javascript">
    function sayHi(){
      alert("
</script>");
    }
   </script>
</body>
</html>


这样页面会加载报错呢~~~


JavaScript 代码将被从上至下解释

  • 解释器会解释一个函数的定义,然后将该定义保存在自己的环境当中。
  • 在解释器对 <script> 元素内部的所有代码求值完毕以前,页面中的其余内容,都不会被浏览器加载或显示。
  • 无论如何包含代码,只要不存在 defer 和 async 属性,浏览器都会按照 <script> 元素,在页面中出现的先后顺序,对它们依次进行解析。 在第一个 <script> 元素包含的代码解析完成之后,第二个 <script> 元素包含的代码才会被解析,然后才是第三个,第四个~~~~

延迟脚本 注意事项


HTML 4 为 <script> 标签定义了 defer 属性,只适用外部脚本文件,这个属性用途是表明脚本在执行时,不会影响页面的结构。

脚本会被延迟到整个页面都解析完毕后再运行,使用了这个属性之后,相当于告诉浏览器立即下载,但延迟执行。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
  <title>小又又 学习 前端 </title>
  <meta name="keywords" content="小又又,学前端">
  <meta name="description" content="小又又的描述测试~~~~~~">
  <meta name="author" content="小又又">
  <script defer="defer" src="example1.js"></script>
  <script defer="defer" src="example2.js"></script>
</head>
<body>
  你好, 小又又~~~
</body>
</html>


在上面这个例子中,虽然两个 <script> 标签 放在了页面 标签中,但是其中包含的脚本将延迟到浏览器 遇到 标签后执行。

HTML 5 规范 要求 脚本按照他们出现的先后执行,因此 第一个延迟脚本会比第二个延迟脚本先执行,但是,实际上,延迟脚本不一定会按顺序执行,因此最好文档中只包含一个延迟脚本。


异步脚本 注意事项

HTML 5 为 <script> 标签定义了 async  属性,与  defer 属性 类似,都是处理改变脚本行为,也都只适用外部脚本文件。

使用了这个属性之后,相当于告诉浏览器立即下载,但是不保证执行顺序。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
  <title>小又又 学习 前端 </title>
  <meta name="keywords" content="小又又,学前端">
  <meta name="description" content="小又又的描述测试~~~~~~">
  <meta name="author" content="小又又">
  <script async src="example1.js"></script>
  <script async src="example2.js"></script>
</head>
<body>
  你好, 小又又~~~
</body>
</html>

指明 async 属性目的是 不让页面等待两个脚本的下载和执行,从而异步加载页面其他内容。

建议:

  • 异步脚本不要在加载过程中修改 DOM 结构
  • 多个异步脚本之间,一定要注意互不依赖


外部脚本

基础说明

在 HTML 中嵌入 JavaScript 代码虽然没有问题,但是一般认为最好的做法,还是尽可能使用外部文件来包含 JavaScript 代码。

可维护

遍及不同的 HTML 页面的 JavaScript 会造成维护问题。

  • 把所有的 JavaScript 文件都放在一个文件夹中,维护起来就轻松多了。
  • 而且,开发人员也可以在不触及 HTML 标签的情况下,集中精力编辑 JavaScript 代码。

可缓存

浏览器能够根据具体的设置缓存链接的所有外部 JavaScript 文件。

也就是说,如果有两个页面都是使用同一个文件,那么这个文件只需下载一次。

因此,能够加快页面加载的速度~~~

适应未来

通过外部文件来包含 JavaScript 无需使用前面提到的 XHTML 或 注释 hack,HTML 和 XHTML 包括外部文件的语法是相同的。

对于使用一定要使用外部脚本没有硬性规范规定~~~,但是基于上面三个优点,所以一般推荐使用外部脚本来将 JavaScript 嵌入页面。



案例


在 HTML4 和 HTML5 中使用 <script> 元素导入脚本,是有所不同的~~~

<!-- HTML4 and (x)HTML -->
<script type="text/javascript" src="javascript.js">

<!-- HTML5 -->
<script src="javascript.js">
</script>


禁用 Javascript 的场景


WHY


早期的浏览器都面临一个特殊的问题,即当前浏览器不支持 JavaScript 时,如何让页面平稳的退化,对于这个问题的最终解决方案就是创造了一个 <noscript>元素,用以在不支持 JavaScript 的浏览器中显示替代的内容。


HOW


<noscript> 中可以包含能够在文档 <body> 中的任何 HTML 标签 --- <script> 元素除外。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
  <title>小又又 学习 前端 </title>
  <meta name="keywords" content="小又又,学前端">
  <meta name="description" content="小又又的描述测试~~~~~~">
  <meta name="author" content="小又又">
  <script defer="defer" src="example1.js"></script>
  <script defer="defer" src="example2.js"></script>
</head>
<body>
  你好, 小又又~~~
  <noscript>
    <p>
      很可惜,小又又要告诉你,这个页面不支持 JavaScript 脚本,请注意开启~~~
    </p>
  </noscript>
</body>
</html>

WHEN


包括在 <noscript> 元素中的内容,只能在下列情况下,才会显示出来。

  • 浏览器不支持脚本
  • 浏览器支持脚本,但脚本被禁用


其他情况下,尽管它是页面的一部分,但是用户永远不会在页面上看到它~~~


今日学习总结


今日心情


今日学习了页面怎么嵌入 JavaScript 脚本,主要就是通过 <script> 标签,发现这个标签属性值还比较多,感觉很不错,希望明天学习到更多东西~~~~

本文使用 mdnice 排版