什么是JavaScript 框架?
JavaScript 本身就是一种功能强大的语言,您不需要额外的框架就可创建富互联网应用程序(RIA)。然而使用JavaScript 并不是件容易的事,主要是由于支持多个 Web 浏览器产生的复杂性。与 HTML 和 CSS一样,不同的浏览器有不同的 JavaScript 实现。让 JavaScript 代码实现跨浏览器兼容简直是个噩梦。
JavaScript 框架或库是一组能轻松生成跨浏览器兼容的 JavaScript 代码的工具和函数。每一个库都在众多流行的 Web浏览器的现代版本上进行了可靠的测试,因此,您可以放心地使用这些框架,您的基于 JavaScript 的 RIA 将会在不同浏览器和平台上以类似的方式工作。
除了解决跨浏览器问题,使用 JavaScript 框架可以更容易地编写检索、遍历、操作 DOM 元素的代码。它们不仅提供获取 DOM 元素引用的快捷函数,而且还允许 DOM 遍历函数以菊花链(daisy-chaining)方式查找任意深度的父元素、子元素、兄弟元素。最后,框架还提供一系列函数来更轻松地操作这些对象,可以改变、添加或删除内容本身;或者使用 CSS 样式类来改变元素的外观。
框架的另一重要特性是其改进的事件处理支持。由于不同浏览器的实现方式各不相同,跨浏览器事件处理将会非常艰难。因此 JavaScript 框架通常封装浏览器事件,并提供一组有用的跨浏览器兼容的函数来进行处理。有些框架还会提供一组标准键盘代码来表示基于键盘的事件(如按下 Escape 键、Return 键、光标键,等等)。
所有这些特性都非常有用,但 JavaScript 框架有一个特性对于它最近的流行非常重要 — 支持 Ajax。与 JavaScript 的其他许多方面一样,每个 Web 浏览器往往以不同方式支持 Ajax,这使得以一种在所有 Web 浏览器中都受支持的方式处理 Ajax 变得十分复杂。几乎所有 JavaScript 框架都包含某种形式的 Ajax 库支持,通常提供 Ajax 请求和响应对象,以及用于评价响应、更新 DOM 元素、查询特定请求的帮助函数(helper)。
JavaScript 框架的典型特性
现在,让我们看一看大多数 JavaScript 框架都具备的有用特性。包括:
· 选择器(Selector)
· DOM 遍历
· DOM 操作
· 实用(Utility)函数
· 事件处理
· Ajax
在解释每个特性时,我将会用以下的一个或几个 JavaScript 框架举例说明:Prototype、jQuery、YUI、ExtJS 和 MooTools。尽管每个框架的实现和语法都各不相同,但概念都是相同的。每个框架都有一个详细的 API 参考,可帮助您理解如何使用该特定库中的特性。
选择器
大多数可用的 JavaScript 框架都会实现某种形式的对快速元素选取的支持。通常来说,这些选择器会使获得 HTML 元素引用的过程快很多,并允许通过 ID、类名、元素类型甚至使用一组伪选择器(pseudo-selector)来查找元素。
例如,使用常规 JavaScript,您也许会用以下代码通过 ID 来选择 DOM 元素:
var theElement = document.getElementById(‘the_element’);
与其他框架一样,MooTools 提供了执行此操作的快捷方法。除了选取该元素,MooTools 还可通过一系列实用函数扩展此元素。其语法如下:
var theElement = $(‘the_element’);
如上所示的单美元符号(dollar)函数,在很多(但不是所有)流行的 JavaScript 框架中都可用,而且语法也大体一致。Prototype 库则更进一步,允许通过 ID 一次选取多个元素,并返回元素数组。和 MooTools 一样,可用Prototype 实用函数扩展这些元素。用 Prototype 一次选取多个元素的语法是:
var elementArray = $(‘element_one’, ‘element_two’,‘element_three’);
在 实用函数 一节中,您将会学到更多 JavaScript 框架所提供的简化集合迭代的函数。
在前面的例子中,必须提供需要选取的元素的 ID。然而,如果要选取多个元素(例如,所有图片)或是具有特定 CSS类名的所有表行,那又怎么办呢?MooTools(还有其他库)提供了一个简单的方法来实现此功能 — 双美元符号(dollar-dollar)函数。它的工作方式与单美元符号函数相同,不同之处在于它接受 CSS 元素名、类名、伪选择器作为参数,而不是接受元素 ID 作为参数。例如,要使用 MooTools 选取 Web 页面上的所有图片,将用以下代码:
var allImages = $$(‘img’);
这将返回一个包含文档中的所有图片的数组,其中每一个图片都使用单美元符号函数进行扩展,以包含 MooTools 实用函数。
根据标记名选取元素非常有用,但如果只是想根据 CSS 类选择一个元素子集,该怎么办呢?这也很简单。在下面的例子中,MooTools 将会选择 CSS 类名为 “odd” 的所有表行。这在实现表行条状化(在表行之间交替变化背景色)时将非常有用:
var allOddRows = $$(‘tr.odd’);
实际上,MooTools 提供了实现表行条状化(row striping)的更好方法。在上面的例子中,假设表中的所有奇数行的CSS 类名为 “odd”。以下代码不要求对表行定义任何 CSS 类名:
var allOddRows = $$(‘tbody:odd’);
这是一个伪选择器的例子,将会返回所有符合条件的对象,在本例中为页面中的 tbody(表主体)的所有奇数子元素。MooTools 伪选择器的其他例子包括:
· checked— 选取所有选中的元素(例如,选中的复选框)
· enabled— 选取所有启用的元素
· contains— 选取所有包含作为参数传递给选择器的文本的元素(例如,contains(‘thistext’))
如前所述,并非所有 JavaScript 框架都使用单美元符号函数选取 DOM 元素。在 YUI (Yahoo!User Interface) 库第 3 版中,用以下代码根据 ID 选取元素(请注意 YUI 3 要求在 ID 前传递 ID 选择器符号 #):
var theElement = Y.one(‘#the_element’);
同样,与使用双美元符号函数根据标记或类名检索元素不同的是,YUI 使用了 Y.all 函数:
var allOddRows = Y.all(‘tr.odd’);
ExtJS 使用类似的方式,用以下语法根据 ID 选取元素:
var theElement = Ext.get(‘the_element’);
以下语法用于根据标记和类名选取元素:
var allOddRows = Ext.select(‘tr.odd’);
在下一节中,您将看到 JavaScript 框架如何轻松遍历 DOM,换句话说,就是查找选定元素的父元素、子元素、兄弟元素。您还会学到如何使用库操作 DOM 以修改元素。
DOM 遍历
根据 ID、元素类型或 CSS 类名查找元素非常有用,但如何根据元素在 DOM 树中的位置执行查找呢?换而言之,根据一个给定的元素查找其父元素、子元素、前一个或后一个兄弟元素。例如,看一下清单 1 的 HTML 片段。
清单 1. HTML 片段(一个 HTML 表)
《table》 《thead》 《tr》《th》Name《/th》 《th》Email Address《/th》《th》Actions《/th》 《/tr》 《/thead》 《tbody》 《trid=“row-001”》 《td》Joe Lennon《/td》《td》joe@joelennon.ie《/td》 《td》《ahref=“#”》Edit《/a》 《ahref=“#”》Delete《/a》《/td》 《/tr》 《trid=“row-002”》 《td》Jill Mac Sweeney《/td》 《td》jill@example.com《/td》《td》《a href=“#”》Edit《/a》 《ahref=“#”》Delete《/a》《/td》 《/tr》《/tbody》《/table》
清单 1 用缩进表示每个元素在 DOM 节点树中的位置。在该例中,table 元素是根元素,它有两个子节点,thead 和 tbody。thead 元素只有一个子节点 tr,后者有三个子节点 — 所有 th 元素。tbody 元素有两个子节点,均为 tr 元素,每个 tr 元素又有三个子元素。每行的第三个子元素又有两个子节点,都是 a (锚点)标记。
如您所知,可以使用 JavaScript 框架的 Selector 函数根据 ID 轻松选取元素。在该例中,有两个元素具有 ID — 均为 tr(表行)元素,ID 分别为 row-001 和 row-002。要使用 Prototype 选取第一个 tr 元素,需要用到以下代码:
var theRow = $(‘row-001’);
在前面的小节中,您学会了如何使用选择器根据类型或 CSS 类检索元素。在本例中,可以使用以下语法选取所有 td 元素。
var allCells = $$(‘td’);
这段代码的问题是它将返回 DOM 中的所有 td 元素。但是,如果只希望获取 ID 为 row-001 的行中的 td 元素,怎么办呢?这时就该使用 DOM 遍历函数了。首先,使用 Prototype 选取 ID 为 row-001 的 tr 元素的所有子节点:
var firstRowCells = theRow.childElements();
这将返回 theRow 变量(之前已设为 ID 为 row-001 的元素)的所有子元素的数组。
下一步,假设只希望取得该行的第一个子节点,在本例中,是内容为 “Joe Lennon” 的 td 元素。应使用以下语句:
var firstRowFirstCell = theRow.down();
很简单吧?这种特别的用法等价于:
var firstRowFirstCell = theRow.childElements()[0];
也可以表示为:
var firstRowFirstCell = theRow.down(0);
JavaScript 索引值从零(0)开始,所以以上语句实际上是告诉 JavaScript 选取第一个子元素。要选取第二个子元素(包含joe@joelennon.ie 邮件地址的单元格),可以使用下面的语句:
var firstRowSecondCell = theRow.down(1);
或者,可以在 DOM 兄弟节点间导航。本例中,第二个单元格是第一个单元格的下一个兄弟节点,因此可以使用以下语句:
var firstRowSecondCell = firstRowFirstCell.next();
这与 down() 函数使用了相同的方式,因此可以使用下面的语句选择第三个单元格:
var firstRowThirdCell = firstRowFirstCell.next(1);
除了使用索引查找特定节点外,Prototype 还允许使用 CSS 选择器语法。考虑 清单 1 的例子,找到包含 Jill Mac Sweeney 的明细的行的第二个链接(“Delete” 链接):
var secondRowSecondLink = $(‘row-002’).down(‘a’, 1);
在本例中,可以使用美元符号函数找到 ID 为 row-002 的元素,然后向下遍历 DOM,直到找到下一个后代 a(锚点)元素。
有些框架可以使用 “菊花链” 遍历函数,表示可以将遍历命令互相连接。在 Prototype 中实现前一个例子的另一种方法是:
var secondRowSecondLink = $(‘row-002’).down(‘a’).next();
考虑下面的例子:
var domTraversal =$(‘row-001’).down().up().next().previous();
如您所见,菊花链方式可以将几个 DOM 遍历语句连接起来。实际上,上例实际上选择 tr 元素 row-001,因此菊花链刚好回到了起点!
评论