JavaScript 高级程序设计第二章
第二章
教材: JavaScript 高级程序设计
目录
- 第二章
- 一. script元素
- 1. 介绍
- 2. 标签位置
- 2.1. 推迟执行脚本---defer属性
- 2.2. 异步执行脚本---async属性
- 2.3 动态加载脚本
- 3. 行内代码与外部文件
- 4. noscript元素
- 总结
JavaScript的执行过程:
JavaScript的三个组成
一. script元素
1. 介绍
是将JavaScript插入HTML的主要方法。
具体属性介绍:<script>
元素
两种方式:
- 嵌入行内JavaScript代码,
<script>
内的代码会被从上到下解释。
<script>function sayHi() {console.log("Hi!");}
</script>
如果<script>
元素中出现字符串</script>
时,浏览器解析行内脚本的方式决定了它在看到字符串</script>
时,会将其当成结束的</script>
标签。想避免这个问题,只需要转义字符“\”即可:
<script>function sayScript() {console.log("<\/script>");}
</script>
- 调用外部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 高级程序设计第二章相关推荐
- Javascript高级程序设计第二版第十一章--DOM2,DOM3--笔记
今天跟诸位分享一下,高程,第二版,11章,dom2,dom3 纵观这一章,一个概念,dom在变,现在变,未来变,反正不断的变. 不过变来变去,ie是不支持dom2,dom3,可能未来新版本支持部分do ...
- Javascript高级程序设计第二版第四章--变量,作用域及内存问题--笔记
由于JavaScript 变量松散类型的本质,决定了它是在特定时间用于保存特定值的一个名字而已,变量的值及其数据类型可以在脚本的生命周期内改变.这可能既有趣又强大,同时又容易出问题. 4.1 语法 E ...
- Javascript高级程序设计第二版第七章匿名函数--笔记
匿名函数就是没有名字的函数,有时候也称为拉姆达(lambda)函数. function functionName(){}; 这是一个函数声明 在代码执行以前被加载到作用域中 var functionN ...
- Javascript高级程序设计第二版第十四章--异常--笔记
chaepter 14 错误异常分享. 其实主要是就是 try{ }catch(error){ } finally { } 这个语句的理解. 主要一点: finally 在 return 之后 运行. ...
- Javascript高级程序设计第二版第十二章--Event--笔记
今天给诸位分享一下 chapter 12 Events 所谓事件就是页面与文档窗口发生交互的瞬间.当年事件发生时它可以被预定(程序处理). 事件有两个过程,冒泡过程,或捕获过程. 冒泡是自上而下,捕获 ...
- javascript高级程序设计第一章
看后总结: 1.javascript的组成成分:ECMAscript+DOM+BOM
- 攻下《JavaScript高级程序设计》——第二章 在HTML中使用JavaScript
从上一章我们知道了,JavaScript是一种专门为网页交互而设计的脚本语言,那么,它就免不了和HTML打交道,所以在设计JavaScript的时候,Netscape首要面临的就是,怎么让HTML和J ...
- JavaScript高级程序设计第四版学习--第二十四章
title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...
- 《JavaScript高级程序设计》红宝书第二遍阅读(动手实践)
<JavaScript高级程序设计>红宝书第二遍阅读(动手实践) 第1章--什么是JavaScript 第2章--HTML中的JavaScript 第3章--语言基础 第4章--变量.作用 ...
最新文章
- Java修改全文数字,求大神帮我修改下java计算机代码,数字键只有0和8能用
- Leetcode 187.重复的DNA序列
- 重学《JavaScript 高级程序设计》笔记 第6章对象
- java调用wvsc.exe_c语言 函数的调用方法
- spring boot Exception in Thread “main” java.lang.classNoFoundException
- golang基本语法——变量使用详解
- Qt之问题: Unknown module(s) in QT: multimedia
- Cmakelists 与gcc 调用so库文件,几个名词解释
- JavaScript实现飞机大战小游戏
- 使用 p6spy,拦截到持久层执行的sql及参数
- python雷达成像(SAR)仿真:(三)徙动校正+方位压缩(完结)
- DCM 与CCM模式
- 机器学习-手写数字识别系统
- python + pyqt5 自制exe 随机换壁纸
- 多线程私有数据pthread_key_create
- fuchsia中virtio 后端实现
- Module containing this breakpoint has not yet loaded or the breakpoint adress could not be obtained.
- php网站开发期末大作业,网页设计期末大作业报告..doc
- SCI论文发表中需要经历哪些过程?
- AVFrame相关api内存管理