您的位置:首页 > Web前端 > JavaScript

JavaScript框架比较

2012-09-27 10:32 239 查看

JavaScript框架比较

摘要:现代网站和web应用程序趋向于依赖客户端的大量的javascript来提供丰富的交互。特别是通过不刷新页面的异步请求来返回数据或从服务器端的脚本(或数据系统)中得到响应。在这篇文章中,你将会了解到javascript框架如何更快、更方便的创建互动性强、响应快得网站和web应用程序。

导言:JavaScript是一种面向对象的脚本语言,一直以来用作Web浏览器应用程序客户端脚本接口的选择。JavaScript允许Web开发人员编程与网页上的对象的工作,为凭空操作这些对象提供了一个平台。当JavaScript最初推出时,它通常用来提供一些微不足道的功能,如时钟、在浏览器状态栏中滚动文本。另外一个常用特色就是“rollover link”,即当用户的鼠标滑过对象时,其文本的颜色或背景图片发生改变。然而,近年来Ajax为网络编程带来了全新的互动,JavaScript几经发展变得更加有用。在Ajax之前,任何服务器端处理或数据库访问都需要整页面被“刷新”或由浏览器呈现新的页面。这不仅缓慢,令用户失望,而且也浪费了带宽和资源。

Ajax就是异步的JavaScript和XML,虽然引用XML不在有效,但是Ajax能对除了XMl的其它几种格式的数据作出响应,如JSON(JavaScript对象表示法)。 Ajax的工作原理是,以异步的方式提交一个 HTTP请求提交到web服务器,不刷新也不呈现整个页面,仅呈现响应的内容。相反,开发人员通常使用DOM(文档对象模型)操作修改网页的一部分,HTTP响应返回的数据将反映这些改变。

什么是JavaScript框架?

JavaScript本身是一种非常强大的语言,你不需要任何额外的框架就可以创建由它支持的富互联网应用系统(RIA)。但是,使用JavaScript并不是一件容易的事,主要是因为在试图提供多种浏览器支持时各种并发症的出现。和HTML和CSS一样,不同的浏览器的JavaScript执行方式不同,那么确保您的JavaScript代码跨浏览器兼容可以说是一个恶梦。

一个JavaScript框架或库实际上是一系列工具和函数,它能更容易产生跨浏览器兼容的JavaScript代码。每个库在许多流行的最新版本的Web浏览器经过了严格测试。因此,您完全可以相信,使用这些框架中的任何一个,您的基于JavaScript的RIA在不同的浏览器和平台中将大体一致。

除了浏览器兼容性问题外,JavaScript框架可以更容易地编写代码去获取、遍历及操纵DOM元素。它们不仅能提供一个快捷的函数来获取一个DOM元素的引用,而且还允许菊花式的DOM遍历函数链查找父母、子女或任何深度的兄弟节点元素。最后,框架提供了一系列的函数,使其更容易的操纵这些对象,允许其内容更改、添加、删除,或者操纵class的样式而影响元素的外观。

JavaScript框架的另一个重要特色就是能更好的支持事件处理。由于浏览器之间的不同实现,跨浏览器事件处理可以说是一个恶梦。因此,JavaScript框架通常将浏览器事件包装起来,并提供一系列有用的跨浏览器函数来处理它们。一些框架也提供了标准化的代表键盘键码系列的事件(如Esc键、Enter键、光标等等)。

所有这些功能是非常有用的,JavaScript框架已在其最近流行Ajax应用中起重要作用。和JavaScript其他方面一样,每个Web浏览器倾向于支持以不同的方式Ajax,使Ajax支持所有的浏览器将是很繁重的工作。几乎所有的JavaScript框架都包括一定形式的Ajax库,通常是提供Ajax请求和响应对象,在对响应作出评价后,更新DOM元素,轮询一个特定的请求。

一个JavaScript框架的典型特征

现在让我们看看大多数JavaScript框架都具有的一些功能。这些特色有:

选择器
DOM遍历
DOM操作
实用函数
事件处理
Ajax

为了更好的诠释这些特色,我将从下面一个或多个JavaScript框架中列举一个例子:Prototype, jQuery, YUI,ExtJS和 MooTools。虽然每个框架的执行情况和语法不同,但其概念大致相同。每个框架有一个详细的API参考,你可以参考它决定如何使用这些特定库的特色功能。

选择器

大多数JavaScript框架可实现某种形式的快速元素选择。一般来说,这些选择器使获取一个元素的引用更加快捷,并允许你通过ID、class、元素类型或一些伪类选择符来选取元素。

例如,使用通常的JavaScript,你可以使用下面的代码借助ID来取得DOM元素。

var theElement = document.getElementById('the_element');

与其他几个框架一样,MooTools提供了一个执行该操作的快捷方法。除了选择元素,MooTools通过自己一系列的功能函数扩展了元素。

var theElement = $('the_element');

$函数在几个流行的框架(并非全部)中可用,其语法大致相同。Prototype更深一层,通过ID在任何时候可以选择多个元素,返回的是一个元素数组。与

MooTools一样,这些元素利用Prototype的实用函数扩展。利用Prototype库在任何时候选择多个元素的语法是这样的:

var elementArray = $('element_one', 'element_two', 'element_three');

在实用函数这一部分,你将了解到JavaScript框架提供的一些函数迭代我们的集合更加容易。

在前面的例子,你必须提供你欲选择元素的ID。但是,你要选择多个元素该怎么办?所有image、拥有特定className的表格的每一行。MooTools(其它的几个库)提供了一个非常简单的方法来做到这一点--$$函数。除了元素的ID外,他还可以接受以下参数:元素的名字、类名以及伪类选择器,其工作原理与$函数相似。例如,使用MooTools获取页面上所有的图片,你可以使用下面的代码:

var allImages = $$('img');

这将得到文档中所有imag的数组,每一个通过$函数和其实用函数进行扩展。

通过tag标签来选取对象是非常有用的,但如果你只想基于元素的class选取它的部分子集,遮盖怎么办?同样很简单。在下面的例子中,MooTools将选择table中class为“odd”的行,这在对每行进行操作时很有用(交替变换表格每一行的颜色)。

var allOddRows = $$('tr.odd');

事实上,MooTools提供了一个更好的方法执行行操作。在前面的例子中,假定table的奇数行授予了类名“odd”。那么下面的代码不需要在table的每一行上定义任何类名。

var allOddRows = $$('tbody <IMG class="wp-smiley" alt=:o src="http://www.denisdeng.com/wp-includes/images/smilies/icon_surprised.gif"> dd');

这是一个伪类选择器的例子,它返回匹配规范的任何对象。在这个例子中,结果为页面中tbody元素中所有奇数行的子元素。MooTools其它伪类元素的例子包括:

checked 所有被选中的元素(例如:选中的复选框);
enabled 所有可用的元素;
contains 所有包含文本(作为参数传递给选择器)的元素。

如前所述,并非所有的JavaScript框架都使用$函数来选取DOM元素。在YUI(Yahoo用户界面)的第三个版本中,下面的代码是通过ID来选取元素的(注意:YUI3需要在ID前加上字符#)。

var theElement = Y.one('#the_element');

同样,通过tag或class来选取元素也不是使用$$函数,在YUI中你要使用Y.all来代替。

var allOddRows = Y.all('tr.odd');

ExtJS以同样的方式工作,通过ID选择元素用下面的语法:

var theElement = Ext.get('the_element') ;

而通过tag和class来获取元素则用下面的语法:

var allOddRows = Ext.select('tr.odd');

在下一章中,你将了解到如何使用JavaScript框架来轻松遍历DOM对象,换句话说,找到与选定元素有父子和兄弟关系的元素。

DOM遍历

基于ID、元素类型、类名查找元素非常有用,但是如果你想基于它在DOM树中的位置来查找元素该怎么办?换句话说,你有一个给定的元素,你想查找它的父元素、子元素中的一个、它的上一个或下一个节点兄弟节点。例如,采用下面这段零碎的HTML代码:

清单1:HTML碎片(一个table)

<table>

<thead>

<tr>

<th>Name</th>

<th>Email Address</th>

<th>Actions</th>

</tr>

</thead>

<tbody>

<tr id="row-001">

<td>Joe Lennon</td>

<td>joe@joelennon.ie</td>

<td><a href="#">Edit</a> 

<a href="#">Delete</a></td>

</tr>

<tr id="row-002">

<td>Jill Mac Sweeney</td>

<td>jill@example.com</td>

<td><a href="#">Edit</a> 

<a href="#">Delete</a></td>

</tr>

</tbody>

</table>

清单1使用缩进来说明其中每个元素节点在DOM树中的位置。在这个实例中,table元素是根元素,有两个子节点thead和tbody。thead元素有一个tr子节点,tr有三个孩子--所有的th元素。tbody元素有两个tr子节点,每个tr节点有三个孩子。在上述每一行的第三个节点中进一步包含子节点,都是两个链接标记。

正如你知道的那样,你可以使用一个JavaScript框架的选择函数通过ID很轻松的选择一个元素。在这个实例中,有两个元素拥有ID,它们是ID分别为row-001和row-002的tr元素。使用Prototype库选择第一个tr,可以使用下面的代码:

var theRow = $('row-001');

在上一章,你还了解到,基于元素的类型或class使用选择器来获取元素。在这个实例中,你可以使用下面的语法来得到所有的td元素。

var allCells = $$('td');

改代码的主要问题在于它返回了每一个td 元素。但是,如果你只想得到ID为row-001的tr的所有td元素该怎么办?这正是DOM遍历函数发挥作用的地方。首先,让我们使用原型来选择ID为row-001的tr的所有的子级。

var firstRowCells = theRow.childElements();

这将返回theRow变量(你最初设置的ID为row-001的tr)所有子元素的数组。

接下来,我们假设你只想得到该行的第一个子元素。在本例中,即包含“Joe Lennon”文本的td元素。要做到这一点,使用下面的语句:

var firstRowFirstCell = theRow.down();

真简单!这个特定的使用方法等价于:

var firstRowFirstCell = theRow.childElements()[0];

也可以这样表示:

var firstRowFirstCell = theRow.down(0);

JavaScript的索引从零开始,所以上面的语句主要告知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’ 详细信息的链接(“删除”链接)。

var secondRowSecondLink = $('row-002').down('a', 1);

在本例中,使用$函数来查找ID为row-002的那一行,向下遍历到第二个后代a元素(锚点)。

一些框架还允许“菊花链式”的遍历功能,这意味着你可以彼此连接遍历命令。上面的例子中,Prototype库的另一种表达方式是这样的:

var secondRowSecondLink = $('row-002').down('a').next();

看看下面的例子:

var domTraversal = $('row-001').down().up().next().previous();

正如你所见,菊花链允许你连接多个DOM遍历语句。事实上,上述例子实际上最终选择ID为row-001的tr元素,所以菊花链又回到了开始的地方。

DOM操作

在此之前,你已经看到JavaScript框架使用选择器和DOM遍历可以很容易的获得特定的元素。但是,为了改变网页上特定元素的内容和外观,你需要操作DOM并应用改变。使用纯粹的JavaScript将是一件繁重的工作,但幸运的是,大多数JavaScript框架提供有用的函数,可以很容易地做到这些。

假设你有一个ID为the-box的盒子。

<div id="the-box">Message goes here</div>

使用jQuery将其文本改变为“Message goes here”,可以很简单的这样使用:

$('#the-box').html('This is the new message!');

事实上,你可以在函数中使用HTML代码,它能被浏览器解析,例如:

$('#the-box').html('This is the <strong>new</strong> message!');

在本例中,DIV元素中的内容看起来像这样:

<div id="the-box">This is the <strong>new</strong> message!'</div>

当然,在实例中你需要使用大于或小于等特殊字符,而不是指定特殊的HTML实体代码。你可以使用jQuery的text函数来代替:

$('#the-box').text('300 >200');

div元素更新后代码如下:

<div id="the-box">300 > 200</div>

在上面的例子中,现有的内容被替换为新的内容。如果你只想给文本附加一些信息该怎么办?幸运的是,jQuery提供append函数达到此目的。

$('#the-box').append(', here goes message');

对原始的div作如上操作后,div元素里的内容看起来是这样的:

<div id="the-box">Message goes here, here goes message</div>

除了追加,你可以在前面追加内容,将其插入到现存内容的前面而不是后面。此外,jQuery提供的函数可以在给定元素内插入内容,要么在前要么在后。还有函数替换内容、清空内容、移除元素、克隆元素等等。

除了DOM操作函数外,JavaScript框架通常还包含几个函数操作元素的样式和class。例如,你有一个表格,当鼠标经过时高亮显示某行。你可以创建一个特殊的类名hover,你可以将该类动态的添加到某行。利用YUI你可以使用下面的代码判断该行是否拥有hover类名,有则免之,无则加之。

if(row.hasClass('hover')) row.removeClass('hover'); else row.addClass('hover');

同样,大多数JavaScript框架都拥有操作CSS的内置函数。

实用函数

许多JavaScript框架都带有大量的实用函数,这些函数使得应用JavaScript开发应用程序更加容易。这篇文章有太多内容需要补充,所以我将讨论大多数框架中更为引人注目的函数中的一个。

如果你曾经使用过JavaScript数组,你可能对使用循环来迭代数组操作其值非常熟悉。例如,想想清单2的代码:

清单2:迭代JavaScript数组的传统方法

var fruit = ['apple', 'banana', 'orange'];

for(var i = 0; i < fruit.length; i++) {

alert(fruit[i]);

}

清单2中的代码没错,但有点麻烦。大多数JavaScript框架包括each功能,它为数组中的每一个元素调用一个特定的函数。使用MooTools,用清单3中的代码可以完成清单2中相同的操作。

清单3:使用MooTools的each函数

['apple', 'banana', 'orange'].each(function(item) {

alert(item);

});

清单3中在语法上与Prototype和jQuery是相同的,YUI 和 ExtJS.略微不同。但是,当应用到hash或对象时,不同的框架语法是不同的。例如,在MooTools中,你可以使用下面清单中的代码:

清单4:对键/值对的各个对象使用MooTools的each函数

var hash = new Hash({name: "Joe Lennon", email: "joe@joelennon.ie"});

hash.each(function(value, key) {

alert(key + ": " + value);

});

但是,使用Prototype库,这看起来就像清单5的代码:

清单5:对键/值对的各个对象使用Prototype的each函数

var hash = $H({name: "Joe Lennon", email: "joe@joelennon.ie"});

hash.each(function(pair) {

alert(pair.key + ": " + pair.value);

});

每个框架包含了许多更实用的函数,通常分为String函数、 Number函数、Array函数、Hash函数、 Date函数等等。要了解更多信息,请参阅相关JavaScript框架的API手册。

事件处理

每个JavaScript框架都实现跨浏览器的事件处理,鼓励你摆脱旧式的内联附加事件而使用精简的线性方法。看看清单6的jQuery例子,使用hover事件高亮显示div元素。

清单6:使用jQuery附加hover事件

$('#the-box').hover(function() {

$(this).addClass('highlight');

}, function() {

$(this).removeClass('highlight');

});

这是jQuery的一个特殊事件,你会发现它提供了两个函数。第一个在onMouseOver事件触发时调用,第二个函数在onMouseOut事件触发时调用。这是因为hover没有标准的DOM事件。让我们看看更为典型的事件,如click(瞧瞧清单7):

清单7:使用jQuery附加click事件

$('#the-button').click(function() {

alert('You pushed the button!');

});

正如你看到的那样,实例中只有一个函数参数。jQuery中大多数事件均采用同样的方式处理,在jQuery中使用事件处理程序,上下文指的是触发事件的哪个对象。一些框架并不以这种方式工作,拿Prototype来说,清单7中的代码看起来就像清单8中的那样。

清单8:使用Prototype附加click事件

$('the-button').observe('click', function(e) {

alert('You pushed the button!');

});

你首先会注意到,没有click函数,而是一个observe函数,它在引用自身之前接受一个事件参数。您还会注意到该函数接受一个参数e,这里的上下文指的是触发事件的元素。看看它如何工作,让我们用Prototype重写清单6中的代码(看清单9)。

清单9:使用Prototype附加悬停事件

$('the-box').observe('mouseover', function(e) {

var el = Event.element(e);

el.addClassName('highlight');

});

$('the-box').observe('mouseout', function(e) {

var el = Event.element(e);

el.removeClassName('highlight');

});

jQuery也不同,你只需要使用$函数得到上下文变量,Prototype库则使用Event.element() 函数。此外,你注意到你需要将mouseover和mouseout 事件分开。

通过该文章的一些教程,你可以看到函数以内联的方式创建,并不命名。这意味着它不能重复使用,Prototype的悬停示例也给了我们一个如何使用命名函数的机会。清单10说明了这个方法。

清单10:使用Prototype改进悬停事件

function toggleClass(e) {

var el = Event.element(e);

if(el.hasClassName('highlight'))

row.removeClassName('highlight');

else

row.addClassName('highlight');

}

$('the-box').observe('mouseover', toggleClass);

$('the-box').observe('mouseout', toggleClass);

您会注意到,此时你只需定义一个函数。它同时被mouseover和mouseout事件调用。该函数根据元素是否有“highlight”的类名,并基于结果添加或删除之。你也会注意到,参数e隐式传递。换句话说,你给observe函数传递了一个不明确的参数。

Ajax

使用JavaScript框架最令人信服的理由是跨浏览器的标准化Ajax请求。Ajax请求是异步的HTTP请求,向服务器端脚本发送请求,然后得到一个响应结果,如如XML、JSON、HTML、纯文本格式的数据。大多数JavaScript框架有一定形式的Ajax请求对象,它接受一系列选项作为参数。这些选项包括回调函数,在得到Web服务器的响应时调用,ExtJS、MooTools和Prototype的Ajax请求看起来是这样的:

清单11:一个ExtJS 库中的Ajax请求

Ext.Ajax.request({

url: 'server_script.php',

params: {

name1: 'value1',

name2: 'value2'

},

method: 'POST',

success: function(transport) {

alert(transport.responseText);

}

});

ExtJS接受一个参数,包括url、params、method 和succcess处理函数等字段,url字段包含服务器端脚本的地址,被Ajax请求调用。Params本身就是一个对象,由键/值对组成,然后传递到服务器。method 字段有两个可选值:GET或POST,默认为post方法。最后一个字段是succcess,在服务器得到成功响应后调用。该例中,假定服务器端返回纯文本,这个文本通过alert()方法呈现给用户。

接下来,让我们进一步探讨MooTools中 Ajax的请求。

清单12:MooTools中的Ajax请求

new Request({

url: 'server-script.php',

data: {

name1: 'value1',

name2: 'value2'

},

method: 'post',

onComplete: function(response) {

alert(response);

}

}).send();

正如你看见,MooTools与ExtJS很相似。你会注意到,变量通过data字段传递,方法字段需要小写。此外,与success处理函数不同,MooTools使用onComplete函数。最后,与ExtJS不同,MooTools实际上用Request的send()函数发送请求。

最后,让我们看看Prototype 有哪些明显的不同。

清单13:Prototype 中的Ajax请求

new Ajax.Request('server-script.php', {

params: {

name1: 'value1',

name2: 'value2'

},

method: 'post',

onSuccess: function(transport) {

alert(transport.responseText);

}

});

看看,Prototype以同样的方式工作,但语法小有差异。对于初学者来说,原型的Request对象接受两个参数传递给构造函数。第一个参数是发送请求的URL地址,正如你在前面两个例子看到的那样,第二个参数是一个对象,包含各个Ajax请求的选项。当然,URl作为一个单独的参数传递,他不在选项列表中。另外,值得注意的是,与MooTools不同,Prototype 对象的构造函数隐式的发送请求,所以不需要调用任何方法触发HTTP请求。

大多数JavaScript框架对Ajax的支持已经超越了我这里所说的。一些明显的增强功能包括在接到响应后自动更新元素,而无需任何特殊的onSuccess 函数。一些库已经预先构建了自动完成功能,正如你在google搜索引擎看到的那样,在键入时给你一些查询建议。

在接下来的章节中,您将了解到JavaScript框架给络开发者带来的用户体验(UE)的提升。

提升用户体验(UE)

到目前为止,这篇文章完全集中于使用JavaScript框架的好处,以及如何更容易的构建交互式应用程序。但是,另一方面,各个框架都有各自诱人的前景,包括用户界面(UI)组件和用户体验(UE)增强,这需要花大量的精力。

这章将分别探讨下面框架的用户体验:Prototype、 jQuery、YUI、ExtJS和MooTools。

Prototype

Prototype是少数几个不包括现成的UI组件或用户体验提升。相反,它顺从所有姊妹库script.aculo.us (Scripty2,这是所知的最新版本)。script.aculo.us 增加了对Prototype效果和行为的广泛支持。这些效果包括:高亮、变形、折叠、震颤、滑动、膨胀。script.aculo.us 还支持拖拽、滑动、Ajax实时编辑以及自动提示。Script.aculo.us将控件(如:slider和autocomplete)的设计交给开发者,没有提供标准的皮肤。

jQuery

与Prototype库不一样,jQuery的核心中包括一些基本的用户体验。这与Script.aculo.us的一些简单效果相似,如slide、fade。但是,对于更为高级的用户体验功能,你需要下载 jQuery UI库,其中包括更多的效果,如拖拽、缩放、排序。与Script.aculo.us不同,jQuery UI还包括一些小的部件或组件,并给开发者提供更具吸引力的借口,这样开发更为简单。目前,这些组件包括: Accordion、 Datepicker、Dialog、Progressbar、Slider和Tabs。这些部件完全主题化,jQuery
UI有广泛的主题,可以用来满足自己网站或网络应用程序的需要。图1显示了jQuery UI Datepicker部件和苹果主题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: