第二章

教材: JavaScript 高级程序设计

目录

  • 第二章
  • 一. script元素
    • 1. 介绍
    • 2. 标签位置
      • 2.1. 推迟执行脚本---defer属性
      • 2.2. 异步执行脚本---async属性
      • 2.3 动态加载脚本
    • 3. 行内代码与外部文件
    • 4. noscript元素
  • 总结


JavaScript的执行过程:

JavaScript的三个组成

一. script元素

1. 介绍

是将JavaScript插入HTML的主要方法。
具体属性介绍:<script>元素

两种方式:

  1. 嵌入行内JavaScript代码,<script>内的代码会被从上到下解释。
<script>function sayHi() {console.log("Hi!");}
</script>

如果<script>元素中出现字符串</script>时,浏览器解析行内脚本的方式决定了它在看到字符串</script>时,会将其当成结束的</script>标签。想避免这个问题,只需要转义字符“\”即可:

<script>function sayScript() {console.log("<\/script>");}
</script>
  1. 调用外部JavaScript文件
<script src="example.js"></script>

注意
使用了src 属性的<script>元素不应该再在<script></script>标签中再包含其他JavaScript代码。如果两者都提供的话,则浏览器只会下载并执行脚本文件,从而忽略行内代码。

<script>元素的src 属性可以是一个完整的URL,而且这个URL 指向的资源可以跟包含它的HTML 页面不在同一个域中,比如这个例子:

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

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

浏览器会按照<script>在页面中出现的顺序依次解释它们,前提是它们没有使用defer 和async 属性。第二个<script>元素的代码必须在第一个<script>元素的代码解释完毕才能开始解释,第三个则必须等第二个解释完。

还有一种行内式

<input type="submit" id="baidu" value="百度一下" onclick="alert('查找失败')">

点击时弹出查找失败。onclick表示点击,alert表示弹出框。
HTML中使用双引号,js中使用单引号。

2. 标签位置

过去所有<script>元素都被放在页面的<head>标签内这种做法的主要目的是把外部的CSS 和JavaScript文件都集中放到一起。不过,把所有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>
</html>

这样一来,页面会在处理JavaScript 代码之前完全渲染页面。用户会感觉页面加载更快了,因为浏览器显示空白页面的时间短了。

2.1. 推迟执行脚本—defer属性

<script>的defer属性表示脚本会被延迟到整个页面都解析完毕后再运行,即等浏览器解析完</html>后才会执行。

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

当两个脚本都有defer属性时,会按照它们出现的顺序进行执行(但最好只包含一个这样的脚本)。

defer 属性只对外部脚本文件才有效。这是HTML5 中明确规定的,因此支持HTML5的浏览器会忽略行内脚本的defer 属性。

2.2. 异步执行脚本—async属性

给脚本添加async 属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改DOM。

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

在这个例子中,第二个脚本可能先于第一个脚本执行。因此,重点在于它们之间没有依赖关系。

2.3 动态加载脚本

通过向DOM中动态添加script元素可以加载指定的脚本。

因为所有浏览器都支持createElement()方法,但不是所有浏览器都支持async 属性。因此,
如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:

let script = document.createElement('script');
script.src = 'gibberish.js';
script.async = false;
document.head.appendChild(script);

第三行表示使用同步加载,同时这种方式获取的资源对浏览器预加载器是不可见的,会影响它们在资源获取队列中的优先级,根据应用程序的工作方式以及怎么使用,这种方式可能会严重影响性能。

想让预加载器知道这些动态请求文件的存在,可在文档头部显式声明它们:

<link rel="preload" href="gibberish.js">

一些点:

  • XHTML规则更为严格,有时候需要将元素内容部分的一些特殊符号替换成对应的HTML实体形式进行表示。
  • type属性默认不指定。
  • 对于<script>标签中的内容,支持JavaScript的浏览器会识别出来并应用JavaScript的规则来解析,对于不支持的为了隐藏嵌入的JavaScript代码。需要将脚本代码包含在一个HTML注释中。形如:
<script><!--function sayHi(){console.log("Hi!");}
//--></script>

使用这种格式,Mosaic 等浏览器就可以忽略<script>标签中的内容,而支持JavaScript 的浏览器则必须识别这种模式,将其中的内容作为JavaScript 来解析。

3. 行内代码与外部文件

推荐将JavaScript代码放入外部文件的理由如下。

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

4. noscript元素

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

<noscript>元素可以包含任何可以出现在<body>中的HTML 元素,<script>除外。在下列两种
情况下,浏览器将显示包含在<noscript>中的内容:

  • 浏览器不支持脚本;
  • 浏览器对脚本的支持被关闭。

任何一个条件被满足,包含在<noscript>中的内容就会被渲染。否则,浏览器不会渲<noscript>中的内容。

<!DOCTYPE html>
<html><head><title>Example HTML Page</title><script defer="defer" src="example1.js"></script><script defer="defer" src="example2.js"></script></head><body><noscript><p>This page requires a JavaScript-enabled browser.</p></noscript></body>
</html>

这个例子是在脚本不可用时让浏览器显示一段话。如果浏览器支持脚本,则用户永远不会看到它。

总结

JavaScript 是通过<script>元素插入到HTML 页面中的。这个元素可用于把JavaScript 代码嵌入到HTML 页面中,跟其他标记混合在一起,也可用于引入保存在外部文件中的JavaScript。

本章的重点可以总结如下。

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

JavaScript 高级程序设计第二章相关推荐

  1. Javascript高级程序设计第二版第十一章--DOM2,DOM3--笔记

    今天跟诸位分享一下,高程,第二版,11章,dom2,dom3 纵观这一章,一个概念,dom在变,现在变,未来变,反正不断的变. 不过变来变去,ie是不支持dom2,dom3,可能未来新版本支持部分do ...

  2. Javascript高级程序设计第二版第四章--变量,作用域及内存问题--笔记

    由于JavaScript 变量松散类型的本质,决定了它是在特定时间用于保存特定值的一个名字而已,变量的值及其数据类型可以在脚本的生命周期内改变.这可能既有趣又强大,同时又容易出问题. 4.1 语法 E ...

  3. Javascript高级程序设计第二版第七章匿名函数--笔记

    匿名函数就是没有名字的函数,有时候也称为拉姆达(lambda)函数. function functionName(){}; 这是一个函数声明 在代码执行以前被加载到作用域中 var functionN ...

  4. Javascript高级程序设计第二版第十四章--异常--笔记

    chaepter 14 错误异常分享. 其实主要是就是 try{ }catch(error){ } finally { } 这个语句的理解. 主要一点: finally 在 return 之后 运行. ...

  5. Javascript高级程序设计第二版第十二章--Event--笔记

    今天给诸位分享一下 chapter 12 Events 所谓事件就是页面与文档窗口发生交互的瞬间.当年事件发生时它可以被预定(程序处理). 事件有两个过程,冒泡过程,或捕获过程. 冒泡是自上而下,捕获 ...

  6. javascript高级程序设计第一章

    看后总结: 1.javascript的组成成分:ECMAscript+DOM+BOM

  7. 攻下《JavaScript高级程序设计》——第二章 在HTML中使用JavaScript

    从上一章我们知道了,JavaScript是一种专门为网页交互而设计的脚本语言,那么,它就免不了和HTML打交道,所以在设计JavaScript的时候,Netscape首要面临的就是,怎么让HTML和J ...

  8. JavaScript高级程序设计第四版学习--第二十四章

    title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...

  9. 《JavaScript高级程序设计》红宝书第二遍阅读(动手实践)

    <JavaScript高级程序设计>红宝书第二遍阅读(动手实践) 第1章--什么是JavaScript 第2章--HTML中的JavaScript 第3章--语言基础 第4章--变量.作用 ...

最新文章

  1. Java修改全文数字,求大神帮我修改下java计算机代码,数字键只有0和8能用
  2. Leetcode 187.重复的DNA序列
  3. 重学《JavaScript 高级程序设计》笔记 第6章对象
  4. java调用wvsc.exe_c语言 函数的调用方法
  5. spring boot Exception in Thread “main” java.lang.classNoFoundException
  6. golang基本语法——变量使用详解
  7. Qt之问题: Unknown module(s) in QT: multimedia
  8. Cmakelists 与gcc 调用so库文件,几个名词解释
  9. JavaScript实现飞机大战小游戏
  10. 使用 p6spy,拦截到持久层执行的sql及参数
  11. python雷达成像(SAR)仿真:(三)徙动校正+方位压缩(完结)
  12. DCM 与CCM模式
  13. 机器学习-手写数字识别系统
  14. python + pyqt5 自制exe 随机换壁纸
  15. 多线程私有数据pthread_key_create
  16. fuchsia中virtio 后端实现
  17. Module containing this breakpoint has not yet loaded or the breakpoint adress could not be obtained.
  18. php网站开发期末大作业,网页设计期末大作业报告..doc
  19. SCI论文发表中需要经历哪些过程?
  20. AVFrame相关api内存管理

热门文章

  1. 有参考图像的图像质量评估方法及代码(PSNR,SSIM,RMSE,NRMSE,ENTROPY)
  2. 如何使用手机里的Windows系统云桌面?
  3. Fiddler 502问题
  4. Java -- 用文本文档写代码
  5. UC浏览器怎么将mht转HTML,极速模式下的MHT
  6. YUM和PXE自动装机
  7. Android获取手机信息大全
  8. 数学建模学习笔记(2.3)lingo软件求解线性规划问题
  9. Centos7环境下安装WPS以及遇到的问题解决
  10. code generator java_CodeGenerator代码生成器