使用jQuery构建未来Web应用程序

jQuery正在成为Web开发人员首选的JavaScript库,与此同时,人们对富Internet应用程序(Rich Internet Application,RIA)的需求也在不断的增长,随着RIA的增多和功能的日益复杂,JavaScript库将会变得越来越重要,那么jQuery无疑是将您的最佳选择。

51CTO推荐专题: jQuery从入门到精通

示例应用程序在这个Web邮件应用程序的额外小部件中包含了各种东西,展示了如何创建一个客户端的富应用程序,并且根据与页面的交互来更改对象的颜色、大小和位置。通过本文,您将能够掌握创建RIA所需的jQuery工具,并借此打动您的客户。

事件

jQuery内的Events模块是向Web应用程序添加交互性的第一步,因为事件通常是页面上发生的事情的触发器。正如我在简介中提到的,您不应该认为事件只发生在Form元素—实际上,任何元素都能触发事件,因此应该充分利用这一点来更轻松地构建定制的小部件,以及添加一些独特却又不局限于特定Form元素的交互。关于jQuery的相关事件的操作,请参阅51CTO之前报导的文章:分解jQuery对相关控件的事件操作

众所周知,大多数事件都基于Form元素。演示这些方法最好的方式就是使用它们。在开始深入研究可用的函数之前,一定要注意:Events模块针对每个函数都遵循一种模式。每个事件函数都包含两种形式:一个没有任何参数,一个包含一个函数作为参数。

二者间的差异十分重要,而且这对各个函数都是一致的。没有参数的函数将实际激发该事件。换而言之,调用click()将实际导致该按钮被单击。在实际单击该按钮,或其click()函数被调用时,将会调用click(function)。是不是很困惑?这只是文字上的描述,举例说明之后,您就会清楚了。

清单1.jQueryEvent方法  


//makethe"myButton"click.Thiswillcausethebuttontoclickandanyactions  


//tiedtoitwilloccur-forexample,itcouldsubmitaform,orother  


//jQueryactionscouldbetiedtoit.  


$("#myButton").click();  


 


$("#myButton").click(function(){  


$("#myDiv").toggle();  


});  


 


$("#myButton").click(function(){  


$("#myDiv").toggle();  


}).click(); 

此外,您可以想像得到,一些事件是与鼠标紧密相连的。由于这些事件常被误用,所以我将它们包括在第三节。认识到这一点后,jQuery已经用特定的函数替代了其中的一些事件。我将它们列于此,只是为了直接与底层的DOM事件相匹配,但对于所有的实际使用,最好使用其他的方法。

比如,当鼠标在某个元素上按下或释放时,就会调用mousedown(fn)和mouseup(fn)方法。然而,更多时候,却应该调用click()方法,因为此方法也会作为事件抛出,而且它更符合预期的行为,更不容易出错。试想一下这样的情况:用户在某个按钮上按下鼠标,发现错了,立即松开鼠标而不是释放鼠标。

如果用户用所定义的mouseup(fn)在另一个页面元素之上释放鼠标,那么应该发生什么行为呢?理想情况下,这两个函数的使用应该限于对界面的拖放,因为这种情况下单击不会有合适的替代。

Event模块的最后两个方法mouseover(fn)和mouseout(fn)目前在很多Web站点上都很常见。它们常被用来显示悬浮帮助、图片显示所需的相框和基于鼠标指针所在位置而发生的颜色改变。JQuery认识到这两个函数还将很常用,但很多人都不能正确使用它们,这就导致很多错误。

人们并不是有意要将bug引入其代码,而是自己不会编写嵌套组件或应对其他复杂情况的代码。因此,jQuery向Event模块添加了一个新方法来替代这两个函数,这个方法就是hover(fn1,fn2)函数。

清单2.jQuery的Hover方法  


$("tr").hover(function(){  


$(this).css("background","#0000ff");  


},  


function(){  


$(this).css("background","#ffffff");  


}); 

属性

页面交互性的一个体现就是它从页面的某个区域获得信息并将信息传送到其他位置的能力。这可以很具体,比如从一个文本字段获得信息后将信息放入一个表内;也可以很宽泛,比如从一个组合框获得信息后将信息传给服务器,然后将服务器的响应再放入另外一个不同的组合框内。交互性的核心就是页面信息的传递。

在页面上保存信息有很多不同的方式,在页面的某个元素内存储信息的方法就更多样了。您可能会想,一个简单的<p>所包含的信息肯定没有一个文本字段那么多(这不一定正确),因而,访问信息也有很多不同的函数。

同样地,您自己可能已经有了这样的结论:如果能从页面元素获得信息,那么也应该可以在这些元素上放置信息。实际上,每个页面元素都是一个数据对象,其中包含由getter/setter方法封装的变量。JavaBean模型和jQuery的实际差异是方法名称和某些元素不适合特定函数的限制。

在深入研究这些方法之前,让我们先来看看什么信息能存储到页面元素内。简单一些的,像a<p>,可能只包含CLASS或ID信息。而像<img>则可能包含更多信息,比如“src”、“alt”、“width”和“height”。而复杂一些的,像<inputtype="password">则可能包含“defaultValue”、“maxLength”、“readOnly”或“accessKey”等信息。这种潜在变量的多样性促使jQuery创建了一种广义函数来访问它们。这个函数是attr(name),可用来访问来自任何页面元素的信息。我们将通过几个示例来了解其工作原理。

清单3.jQueryattr()函数  



<imgsrcimgsrc="/images/space.gif"id="spacer"class="abc"alt="blank"> 



//Callstotheattr()functionwillreturnthefollowing  


$("#spacer").attr("src");//willreturn"/images/space.gif"  


$("#spacer").attr("alt");//willreturn"blank"  


//Similarly,youcanaccesstheIDinthesameway  


$(img).each(function(){  


$(this).attr("id");//willreturn"spacer"  


}); 

在试图向页面添加交互性时,此函数十分有用。实际上,在添加data()函数(如下所示)之前,通常都必须将所需信息压缩到一个可用变量内。例如,假设有一个页面具有两个框架,第一个框架显示选项卡,底部框架显示每个选项卡的内容,那么可以这样设置:

清单4.应用attr()  


<!--Thiswouldappearinthetopframeasatab.TheCSSfilewouldcontrolhow  



thetabappears,andtheonlyHTMLcodeneededwouldbethis--> 




<td> 




<divclassdivclass="tab"id="/messages.jsp">Messages</div> 




</td> 



 


$(".tab").click(function(){  



window.parent.frames['content'].location=$(this).attr("id");  



}); 

除了获得每个元素上的属性值外,还可以设置这些值。其效果与以编程方式更改元素外观或行为相同。

清单5.利用attr(str)更改属性  


//willchangetheimagesource,andtheimagedisplayedonthepagewillchange  


$("img").attr("src","myimage.jpg");  


 


//willchangeallthelinksonthepagetogotoonespecificpage  


$("a").attr("href","mypage.html");  


 


//willchangethemaxLengthonallpasswordfieldsto10characters  


$(":password").attr("maxLength","10"); 

页面上的Form元素具有一个特殊的函数,该函数可以针对这些元素调用以获得附加到元素的值。在处理表单和验证时,这一点尤其便利,而且在用Form元素创建交互Web站点时更有可能会用到这些函数。

清单6.Form元素的val()函数  


//willgetthetextcontainedinthetextfieldandcheckthatit'snotblank  


$(":textfield").each(function(){  


//usetheval()functiontogetthetextinsidethetextfield  


if($(this).val()=="")  


$(this).next().text("Error");  


});  


 


//onanewpasswordpage,thiswillcomparethenewonewiththeconfirmation,  


//tomakesuretheyareequal  


if($("#newPassword").val()!=$("#confirmPass").val())  


$("#newPassword").next().text("Error"); 

还有其他一些函数,可用来获得包含在某些标记之内的信息。那么这有什么用途呢?比如说,您可以获得包含在某个<td>标记内的所有信息并进行替换,或者您也可以将所有<p>内的文本变成小写的。获得这些信息的方式有两种,但不能为此使用attr()函数。

与所有其他的属性函数类似,这些函数也有相应的setter方法。第一个是html()函数,它能返回某个标记的所有innerHTML。另一个是text(),它能返回某个标记内的所有文本。那么二者有何区别呢?html()函数能返回包括HTML标记在内的文本,而text()则会分离二者,只返回内含的文本。以下示例展示了它们的不同之处。

清单7.html()与text()的对比  



//thiswillexamineevery<td>tag,andifthevalueisblank,itwillinsert  



//a"-"intoit,asaplaceholder.  


$("td").each(function(){  


//checkthetextofthetablecell  


if($(this).text()=="")  


$(this).text("-");  


});  


 


//thiswillconverteveryparagraph'stexttolowercase  


$("p").each(function(){  



varoldText=$(this).text();  




varnewText=oldText.toLowerCase();  



$(this).text(newText);  


});  


 



<--Thisshowsthedifferencebetweentext()andhtml()--> 




<dividdivid="sample"><b>Thisistheexample</b></div> 



 



$("#sample").html();//willreturn"<b>Thisistheexample</b>"  



$("#sample").text();//willreturn"Thisisanexample" 

此外,最近还向jQuery库添加了用于属性的data()函数。它源自jQueryUI项目并且已纳入jQuery的整体项目之中。起初,UI项目开发人员只是觉得他们不想破坏某些页面元素的可用属性,于是就想到要找到一种方法,用来根据自己的需要创建能存储信息的属性。

回顾上文提到过的选项卡的例子。我其实“破坏”了此DIV的ID内的链接,而这显然不是最理想的方法。但是,受jQuery以前版本的限制,这在当时是惟一的选择。有了data()函数之后,这个问题就有了更好的解决方案。不妨将data()函数视为用来访问包含在每个页面元素的内部Map的一种方式。

一个Map实际上就是键-值对的集合。这就让开发人员可以创建他们想要给页面元素提供的任何定制属性,并能给该属性附加任意值。最终的结果就是代码的编写更简单,而且当项目规模不断增大时,代码的维护也更容易。接下来,让我们用新的data()函数重写上文提到的示例:

清单8.新的data()函数  


//createthedivlikewedidabove,butwithoutanyspecificinformation.Inthis  


//waywecancreateagenericHTMLlayoutandcustomizeitinourjQuerycode.  


 



<td> 




<divclassdivclass="tab"></div> 




</td> 



 


//NowcustomizeeachtabinthejQuerycode.  


 


$(".tab").eq(0).text("Messages");  


$(".tab").eq(0).data("link","messages.jsp");  


$(".tab").click(function(){  



window.parent.frames['content'].location=$(this).data("link");  



});  


 


//Takingthisastepfurther,youcanpictureallthisinformationcomingfrom  


//anexternalpropertiesfileviaaJavaarray.ThiswouldbethecodeonaJSP  


//page.  


 



<%  



//arraycontainingtabnames  


String[]tabNames;  


//arraycontainingtablinks  


String[]links;  


 



for(inti=0;i<tabNames.length;i++){  




%> 




$(".tab").eq(<%=i%>).text("<%=tabNames[i]%>");  




$(".tab").eq(<%=i%>).data("link","<%=links[i]%>");  




<%}%> 



 


$(".tab").click(function(){  



window.parent.frames['content'].location=$(this).data("link");  



}); 

CSS处理

本文最后的这个部分将要介绍如何在不调整样式表或重载此页面的情况下动态地处理页面的CSS。我们将能够通过简单更改颜色、字体等向页面添加一些基本效果。jQuery的CSS实际上是整个库最初的创意来源。其目标是让页面上的CSS编程更容易。

正如您所见,此项目随后得到了充分的发展。但是项目的初衷并没有改变,jQuery的确简化了CSS编程。不过,我还是先要说明一点,即jQuery为处理CSS所提供的那些传统函数实际上已经不能适应当今的Web环境。然后,我会介绍可以使用的其他函数(也是jQuery内的)。

有两个基本函数可用来处理页面上的CSS。可以先以字符串传递单个属性,然后再以字符串传递单个值,也可以用字符串/字符串数组的形式一次传递。这两个函数的功能基本相同,并且可以很容易地更改页面的CSS。

清单9.css()函数  


//changethebackgroundofeverydivtored  


$("div").css("backgroundColor","#ff0000");  


//-or-  


$("div").css("backgroundColor","red");  


//-or-  


$("div").css({backgroundColor:"#ff0000"});//noticethebracesandlackofquotes 

可以看出这些函数非常简单直观,很容易理解和掌握。不过,考虑到目前Web页面设计的潮流,这些函数还存在一些问题。常规的Web页面都是从页面删除样式,然后在样式表中填入一个外部文件或代码片段。如果能采用其他办法,您肯定不希望将样式代码放入JavaScript代码中。否则,将来更改站点的外观将十分困难。

幸运的是,现在已经有了替代函数,它既能提供所需的代码分离,又能让CSS处理简单直观。这些函数允许从页面元素添加和删除类。通过将这些类的样式放入外部样式表,就能分离样式、数据和事件,这种分离对于复杂的页面至关重要。请看以下这些示例:

清单10.更佳的CSS处理-addClass()和removeClass()  


$(":textfield").each(function(){  


if($(this).val()=="")  


{  


$(this).next().text("Error");  


//thiswillturnthetextfield'sborder/textred  


$(this).addClass("input_error");  


}  


//thistestsifthetextfieldhastheclassattachedalready  


elseif($(this).hasClass("input_error"))  


{  


$(this).next().text("");  


//thiswillremovetheclass,restoringanormalborder/text  


$(this).removeClass("input_error");  


}  


}); 

如这个示例所示,通过引用在外部样式表内定义的类来调整CSS是一种更可取的处理CSS的方法。它让Web站点创建者通过更改样式表就能改变整个站点错误消息的处理方式,而不再像采用css()方法时那样,必须追究代码的每个实例。虽然这些方法直观易用,但是不太适合大型Web应用程序,应该避免采用addClass()和removeClass()方法。

综合学到的知识

要综合使用以上知识,让我们再来看看这个示例应用程序。它是一个具有交互性的Web应用程序,试图创建一个RIA并给用户这样的感觉:他们处理电子邮件所用的这个Web应用程序非常类似于桌面应用程序。在本例中,将利用Event、Attribute和CSS模块来定义Web邮件应用程序将如何处理鼠标单击和双击。

以下所示的屏幕截图显示了真实的效果。当用户在表的一个行上单击时,此行将会改变颜色以突出显示用户的当前选择。当用户在消息上双击时,用户就能看到消息,但如果用户读的是条新消息,此行的背景颜色会改变以表明此消息不再是未读消息。

使用jQuery构建未来Web应用程序

使用jQuery构建未来Web应用程序

清单11.综合学到的知识  


//Firstweaddtherowstothetable.Eachrowisamemberofthe"messageRow"class.  


//WealsogiveanIDtoeachrow,andthisIDisthemessagenumberitself,whichis  


//gottenfromtheJavadataobject.KeepinmindthissitsinaforloopinaJSPfile.  


 



<%  




for(inti=0;i<messages.size();i++)  



{  



MessageDatamessage=messages.get(i);  




%> 




<trclasstrclass="messageRow"id="<%=message.id%>"> 



 


$(".messageRow").click(function(){  


$(".messageRow").removeClass("message_selected");  


$(this).addClass("message_selected");  


});  


 


$(".messageRow").dblclick(function(){  


if($(this).hasClass("mail_unread"))  


{  


$(this).removeClass("mail_unread");  


}  



$.post("<%=HtmlServlet.READ_MESSAGE%>.do",  



{  


messageId:$(this).attr("id"),  



view:"<%=view%>"},  



function(data){  


//DoAJAXstuffhere  


});  


});  


}); 

结束语

随着应用程序不断从桌面向浏览器转移,像jQuery这样的JavaScript库的将越来越重要。应用程序会越来越复杂,这就使跨浏览器的jQuery成为所有Web应用项目的必要工具。由于易于使用和功能完备,jQuery逐渐从其他JavaScript库中脱颖而出,成为很多开发人员的最佳选择。

文章随后讨论了属性以及如何恰当地从页面元素获得属性,如何在页面元素上设置属性。您看到了通用的attr()函数可用于每个元素,并且Form元素有获得其值的特殊函数。您还看到了新添加到jQuery的data()函数,此函数可充当每个页面元素的HashMap,让程序员可以创建所需的任何属性。

相关推荐