2.4.1 比较操作符
如果想比较两个值是否相等,可以使用等于(==)比较操作符。如果在条件语句的某个条件里使用了单个等号,那么根据相应的赋值操作返回值作为判断条件。
if (a = true) {console.log(true)} // 这里返回值为 true,打印出 true
if (a = false) {console.log(false)} // 这里返回值为 false,代码块里的语句不会执行
3.2 对象:DOM 中的 “O”
“对象” 是一种自足的数据集合。与某个特定对象相关联的变量被称为这个对象的属性,只能通过某个特定对象去调用的函数被称为这个对象的方法。
JavaScript 语言里的对象可以分为三种类型:
- 用户定义对象(user-defined object):由程序员自行创建的对象。
- 内建对象(native object):内建在 JavaScript 语言里的对象,如 Array、Math 和 Date 等。
- 宿主对象(host object):由浏览器提供的对象。
3.4 节点
文档是由节点构成的集合。在 DOM 里有许多不同类型的节点,也有很多类型的 DOM 节点包含着其他类型的节点。
常用的三种节点:元素节点、文本节点和属性节点
3.4.5 获取元素
有 3 种 DOM 方法可获取元素节点,分别是通过元素 ID、标签名和类名来获取。
- getElementById:返回一个给定 id 属性值的元素节点对应的对象。
- getElementsByTagName:返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。
- getElementsByClassName:返回一个具有相同类名的元素的数组(可指定多个类名,只要在字符串参数中用空格分隔类名即可。类名的实际顺序不重要,甚至还带有更多类名也没有关系)。
3.5 获取和设置属性
- getAttribute:返回指定属性名的属性值。它不属于 document 对象,只能通过元素节点对象调用。
- setAttribute:更改属性节点的值。它也只能用于元素节点。
4.4.2 nodeType属性
每一个节点都有 nodeType 属性。nodeType 属性总共有 12 种可取值,但其中仅有 3 种具有实用价值。
- 元素节点的 nodeType 属性值是 1。
- 属性节点的 nodeType 属性值是 2。
- 文本节点的 nodeType 属性值是 3。
5.2 平稳退化
如果正确地使用了 JavaScript 脚本,就可以让访问者在他们的浏览器不支持 JavaScript 的情况下仍能顺利地浏览你的网站。就是说,虽然某些功能无法使用,但最基本的操作仍能顺利完成。
5.2.1 "javascript:" 伪协议
“真”协议用来在因特网上的计算机之间传输数据包,如 HTTP 协议(http://)、FTP 协议(ftp://)等,伪协议则是一种非标准化的协议。"javascript:" 伪协议让我们通过一个链接来调用 JavaScript 函数。
举个栗子:下面通过 "javascript:" 伪协议调用 popUp() 函数:
Example
这条语句在支持 "javascript:" 伪协议的浏览器中运行正常,较老的浏览器则会去尝试打开那个链接但失败,支持这种伪协议但禁用了 JavaScript 功能的浏览器会什么也不做。
总之,在 HTML 文档里通过 "javascript:" 伪协议调用 JavaScript 代码的做法非常不好。
5.2.2 内嵌的事件处理函数
把事件处理函数作为属性嵌入 HTML 标签
举个栗子:下面通过 onclick 事件处理函数调用 popUp() 函数:
Example
因为在上面的这条 HTML 指令里使用了 return false 语句,这个链接不会真的被打开。把 href 属性的值设置为 “#” 只是为了创建一个空链接,实际工作全部由 onclick 属性负责完成。
很遗憾,这个技巧与用 "javascript:" 伪协议调用 JavaScript 代码的做法同样糟糕,因为它们都不能平稳退化。如果用户已经禁用了浏览器的 JavaScript 功能,这样的链接将毫无用处。
5.2.3 谁关心这个
让那些不支持或禁用了 JavaScript 功能的浏览器也能顺利地访问你的网站真的那么重要吗?
请想象一下,如果那个用户是一个搜索机器人。搜索机器人是一种自动化的程序,它们浏览 Web 的目的是为了把各种网页添加到搜索引擎的数据库里。各大搜索引擎都有类似的程序。目前,只有极少数的搜索机器人能够理解 JavaScript 代码。所以,如果你的 JavaScript 网页不能平稳退化,它们在搜索引擎上的排名就可能大受损害。
举个栗子:具体到 popUp() 函数,为其中的 JavaScript 代码预留出退路很简单:
在链接里把 href 属性设置为真实存在的 URL 地址,让它成为一个有效的链接。
Example
所以,在把 href 属性设置为真实存在的 URL 地址后,即使 JavaScript 已被禁用,这个链接也是可用的。这是一个经典的 “平稳退化” 的例子。
5.3.1 结构与样式分离
我们经常会遇到一些几乎每个元素都带有 style 属性的 Web 文档,而这是 CSS 技术最缺乏效率的用法之一。真正能从 CSS 技术获益的方法,是把样式全部转移到外部文件中去。
作为 CSS 技术的突出优点,文档结构与文档样式的分离可以确保网页都能平稳退化。
5.3.2 渐进增强
“标记良好的内容就是一切”
只有正确地使用标记语言才能对内容做出准确的描述。
在给内容加上各种标记后,就可以使用各种 CSS 指令控制内容的显示效果。CSS 指令构成了一个表示层。这个表示层就像是一张透明的彩色薄膜,可以包裹到文档的结构上,使文档的内容呈现出各种色彩。但即使去掉这个表示层,文档的内容也依然可以访问。
所谓 “渐进增强” 就是用一些额外的信息层去包裹原始数据。按照 “渐进增强” 原则创建出来的网页几乎都符合 “平稳退化” 原则。
类似 CSS,JavaScript 和 DOM 提供的所有功能也应该构成一个额外的指令层。CSS 代码负责提供关于 “表示” 的信息,JavaScript 代码负责提供关于 “行为” 的信息。行为层的应用方式与表示层一样。
5.5 向后兼容
正如前面反复强调的那样,你的网站的访问者很可能未启用 JavaScript 功能。此外,不同的浏览器对 JavaScript 的支持程度也不一样。绝大多数浏览器都能或多或少地支持 JavaScript,而绝大多数现代浏览器对 DOM 的支持都非常不错。但比较古老的浏览器却很可能无法理解 DOM 提供的某些方法和属性。因此,即使某位用户在访问你的网站时使用的是支持 JavaScript 的浏览器,某些脚本也不一定能正常工作。
针对这一问题的最简单的解决方案是,检测浏览器对 JavaScript 的支持程度。
5.5.1 对象检测
这个解决方案很容易实现:只要把某个方法打包在一个 if 语句里,就可以根据这条 if 语句的条件表达式的求值结果是 true(这个方法存在) 还是 false(这个方法不存在) 来决定应该采取怎样的行动。这种检测称为对象检测(object detection)。
举个栗子:
window.onload = function () {
if (!document.getElementsByTagName) {
return false;
}
}
虽然只是一条简单的 if 语句,但它可以确保那些 “古老的” 浏览器不会因为我的脚本代码而出问题。这么做是为了让脚本有良好的向后兼容性。因为我在给网页添加各有关行为时始终遵循了 “渐进增强” 的原则,所以可以确切地知道我添加的那些都能平稳退化,我的网页在那些 “古老的” 浏览器里也能正常浏览。那些只支持一部分 JavaScript 功能但不支持 DOM 的浏览器仍可以访问我的网页的内容。
5.6.1 尽量少访问 DOM 和尽量减少标记
访问 DOM 的方式对脚本的性能会产生非常大的影响。不管什么时候,只要是查询 DOM 中的某些元素,浏览器都会搜索整个 DOM 树,从中查找可能匹配的元素。更好的办法是把第一次查询的结果保存在一个变量中,然后重用该结果。
在多个函数都会取得一组类似元素的情况下,可以考虑重构代码,把搜索结果保存在一个全局变量里,或者把一组元素直接以参数形式传递给函数。
另一个需要注意的地方,就是要尽量减少文档中的标记数量。过多不必要的元素只会增加 DOM 树的规模,进而增加遍历 DOM 树以查找特定元素的时间。
5.6.2 合并和放置脚本
包含脚本的最佳方式就是使用外部文件,因为外部文件与标记能清晰地分离开,而且浏览器也能对站点中的多个页面重用缓存过的相同脚本。
把多个脚本文件合并到一个脚本文件中,可以减少加载页面时发送的请求数量。
脚本在标记中的位置对页面的初次加载时间也有很大影响。位于 块中的脚本会导致浏览器无法并行加载其他文件(如图像或其他脚本)。一般来说,根据 HTTP 规范,浏览器每次从同一个域名中最多只能同时下载两个文件。而在下载脚本期间,浏览器不会下载其他任何文件,即使是来自不同域名的文件也不会下载,所有其他资源都要等脚本加载完毕后才能下载。
把所有
推荐几个有代表性的代码压缩工具: 列举几个常用的 DOM 方法: 这些方法都是 DOM Core 的组成部分。它们并不专属于 JavaScript,支持 DOM 的任何一种程序设计语言都可以使用它们。它们的用途也并非仅限于处理网页,它们可以用来处理任何一种标记语言(比如 XML)编写出来的文档。 HTML-DOM 提供了许多描述各种 HTML 元素的属性。 举个栗子: 这些方法和属性可以相互替换。同样的操作既可以使用 DOM Core 来实现,也可以使用 HTML-DOM 来实现。HTML-DOM 代码通常会更短,必须提醒一下,它们只能用来处理 Web 文档。 Ajax 技术的核心就是 XMLHttpRequest 对象。这个对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。以往的请求都由浏览器发出,而 Javascript 通过这个对象可以自己发出请求,同时也自己处理响应。 XMLHttpRequest 对象有许多的方法。其中最有用的是 open 方法,它用来指定服务器上将要访问的文件,指定请求类型:GET、POST、或 SEND。这个方法的第三个参数用于指定请求是否以异步方式发送和处理。 onreadystatechange 是一个事件处理函数,它会在服务器给 XMLHttpRequest 对象返回响应的时候被触发执行。 只要 readyState 属性的值变成了 4,就可以访问服务器发送回来的数据了。 注意:在使用 Ajax 时,千万要注意同源策略。使用 XMLHttpRequest 对象发送的请求只能访问与其所在的 HTML 处于同一个域中的数据,不能向其他域发送请求。
6.8 DOM Core 和 HTML-DOM
document.getElementsByTagName('form')
可简化为:
document.forms
element.getAttribute('src')
可简化为:
element.src
7.4.1 XMLHttpRequest 对象
服务器在向 XMLHttpRequest 对象返回响应时,该对象有许多属性可用,浏览器会在不同阶段更新 readyState 属性的值,它有 5 个可能的值:
访问服务器发送回来的数据要通过两个属性完成。一个是 responseText 属性,这个属性用于保存文本字符串形式的数据。另一个属性是 responseXML 属性,用于保存 Content-Type 头部中指定为 “text/xml” 的数据,其实是一个 DocumentFragment 对象。你可以使用各种 DOM 方法来处理这个对象。而这也正是 XMLHttpRequest 这个名称里有 XML 的原因。