时间记录:24.09.10-24.09.13
笔者之前已经读过几遍红宝书,但是发现之前所读有很多疏忽、遗漏、不深刻的地方,所以最近开始找出《JavaScript高级程序设计(第四版)》进行重读,并进行延伸方向的问题探讨和学习。
如有不正确之处,欢迎评论区讨论🥳
第二章 HTML中的JavaScript
1. <script>
元素—将JS代码插入HTML的主要方法
对于这个老生常谈的元素,有以下几个属性需要格外注意:
- async:可选。表示应立即开始下载脚本,但不能阻止其他页面动作(比如下载资源、等待其他脚本加载)。只对外部脚本文件有效。
- defer:可选。表示脚本可以延迟到文档被完全解析和显示之后再执行。只对外部脚本文件有效(IE7之前版本对内部脚步也可以指定该属性)。
- crossorigin:可选。配置相关请求对CORS设置。默认不使用CORS(跨源资源共享)。
- src:可选。表示包含要执行的代码的外部文件。
- integrity:可选。允许对比 接收到的资源签名 和 指定的加密签名 以验证子资源完整性。如果二者不匹配会报错,该脚本不会执行。
加载JS的其他方法-动态加载脚本:
可以通过JS使用DOM API,向DOM中动态添加script元素
let script = document.createElement('script');
script.src = 'example.js';
document.head.appendChild(script);
1.1. 面试常见问题:defer和async的区别是什么?
<!DOCTYPE html>
<html><head><title>Title</title><script defer src="example1.js"></script><script async src="example2.js"></script></head><body><!-- 页面内容在这里 --></body>
</html>
从改变脚本处理方式上看,async和defer属性都只适用于外部脚本,都会告诉浏览器立即开始下载,但延迟执行。
但是,HTML5规范要求有defer属性的脚本应该按照他们出现的顺序执行(但实际应用中,推迟执行的脚本不一定总会按顺序执行),而标记为async的脚本并不保证能按照它们出现的顺序执行。
细节问题探讨:
-
对于defer属性来说,当浏览器下载完对应的脚本文件,会等到解析完HTML后再执行JS;对于async属性来说,当浏览器下载完对应的脚本文件,会立即中断浏览器解析HTML,执行JS。
-
defer属性在脚本执行时一定可以获取到HTML中已有的元素;async属性在脚本执行时没有确定的执行时机(谁先下载完执行谁),所以不一定能获取到HTML中已有的元素。
-
如果一个脚本同时设置async和defer属性,浏览器会以async的特性加载脚本。(async优先级更高)
XHTML写法:
<!DOCTYPE html>
<html><head><title>Title</title><script defer=“defer” src="example1.js"></script><script async=“async” src="example2.js"></script></head><body><!-- 页面内容在这里 --></body>
</html>
1.2. 当行内脚本出现字符串’</script>
'……
问题出现原因: 行内脚本
因此,当行内JacaScript代码中出现字符串’'时,浏览器会将其视作
<script>function sayJs() {console.log("</script>")}
</script>
解决方法: 使用转义字符- ‘ \ ’ (如代码所示)
1.3. 外部文件和行内代码的优先级,哪个更高?
通常认为的最佳实践是尽可能将JS代码放在外部文件中,
好处是:可维护性好、缓存-文件只需下载一次(页面加载速度会更快)、适应未来-预请求消耗降低。
如果一个文件中同时使用了 具有src属性的标签,浏览器只会下载并执行脚本文件,从而忽略行内代码。(外部文件优先级更高)
1.4. 使用外部文件时潜在的安全隐患…
<script>
元素可以包含来自外部域的JS文件,这很强大,但同时也备受争议。
<script src="https://www.somewhere.com/file.js"></script>
如上例,浏览器在解析这个资源时,会向src属性指定的路径发送一个GET请求,已取得相应资源。
这个初始的请求不受浏览器同源策略限制,但返回并被执行的JS仍受限制。
来自外部域的代码会被当成它页面的一部分来解释和加载,通过这种策略,我们可以通过不同域分发JS。
但是,在引用来自外部域的JS代码时,可能会因为引用目标文件被替换导致安全风险,为了确保目标域可信,可以通过
1.5. 面试常见问题:<script>
元素放在页面的哪个位置更好,为什么?
所有JavaScript引用都放在元素中的页面内容后面,这样一来,页面会在处理JavaScript代码之前完全渲染页面,浏览器显示空白页面的时间会变短,用户会感觉页面加载更快了。
<!DOCTYPE html>
<html><head><title>Title</title></head><body><!-- 页面内容 --><script defer="defer" src="example1.js"></script><script defer="defer" src="example2.js"></script></body>
</html>
2. 文档模式-标准与混杂
混杂模式在所有浏览器中以省略文档开头的doctype声明作为开头
标准模式通过以下几种文档声明类型开启:
<!-- HTML 4.01 Strict -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<!-- HTML5 -->
<!DOCTYPE html>
2.1. 面试常见问题:HTML文件的第一行代码是什么意思?有什么用?
HTML文件的第一行代码实际上是将文档模式切换为了标准模式。
标准模式:让IE具有兼容标准的行为
混杂模式:让IE像IE5一样(支持一些非标准的特性)
标准模式和混杂模式的主要区别只体现在通过CSS渲染的内容方面,但对JavaScript也有一些关联影响(被称作副作用)。
3. <noscript>
— 页面优雅降级的方案
元素中可以包含除了<script>
标签外的、可以出现在中的HTML元素。在浏览器不支持脚本/浏览器对脚本的支持被关闭时触发。
<!DOCTYPE html>
<html><head><title>Title</title><script defer="defer" src="example1.js"></script><script defer="defer" src="example2.js"></script></head><body><noscript><p>this page need a JavaScript-enabled browser.</p></noscript></body>
</html>
注意:如果浏览器支持并启用脚本,则元素中的任何内容都不会被渲染