市面上关于jQuery的书很多,但在我看来,为了学jQuery买书,就像买一本《傻瓜相机操作指南》。如果有必要,只会证明jQuery作为一个JavaScript库,写得不够好。而jQuery恰恰是设计良好,容易掌握正是它的优点之一。学会jQuery,一篇文章的篇幅正合适。当然前提是已经掌握JavaScript语言。
不看注释
先来看几段jQuery代码(片段二和三取自jQuery官方网站首页):
//snippet #1
$( “#container input[type=’checkbox’]” ).attr( “checked”, true);
//snippet #2
var hiddenBox = $( "#banner-message" );
$( "#button-container button" ).on( "click", function( event ) {
hiddenBox.show();
});
//snippet #3
$.ajax({
url: "/api/getWeather",
data: {
zipcode: 97201
},
success: function( data ) {
$( "#weather-temp" ).html( "" + data + " degrees" );
}
});
你能看明白或者猜出这三段代码的意思吗?如果能,并且喜欢它们完成这些事的风格,那么对jQuery你已经入门了。直觉上的好恶,对于选择JavaScript库和挑选手机同样重要。众多的JavaScript库,用每一种都可以完成同样的任务,它们竞争的正是对他们的用户,也就是Web程序员的友好性。
片断一:将id为container内的所有检查框(checkbox)选上。
片断二:给类属性为button-container的容器内的按钮添加单击事件的响应程序,使得id为banner-message的元素显示。
片断三:发出一个XMLHttpRequest,到指定的相对地址,包含一个邮编参数,成功收到响应后,更新id为weather-temp的元素的Html。
既然jQuery的代码是易于理解的,笔者觉得要学会它,不妨多说些它的背景和本质。
JavaScript能做什么?
这里说的JavaScript不包括服务器端和其他软件平台上运行的JavaScript,限定于我们一般所指的在浏览器环境中运行的脚本语言。和其他嵌入在某个软件中的脚本语言一样,JavaScript被设计成完成特定的任务(与C、Java等通用性的语言相对),为此它能够调用环境提供的API(在浏览器中就是DOM接口),而它的功能也囿于这些API。
具体来看,JavaScript能完成的任务可以分为以下几类(这里的讨论限于HTML5成熟之前的范围,即不包括客户端存储技术如操作关系型数据库和文件系统,使用SVG、Canvas等技术画图因为和目前的jQuery库核心功能没有关系也不做讨论)。
JavaScript程序的核心就是操纵通过DOM接口获得的HTML元件(HTML element)和事件编程模型。
jQuery能做什么?
抽象地讨论完JavaScript所做的事情后,我们来看看jQuery是做什么的。和所有的程序开发一样,开发量增大之后,就会发现有很多通用的基本的功能,把它们集中起来,程序库就产生了。网络上大量的JavaScript库就是不同的开发人员按照他们的理念和喜好设计和积累的。笔者在接触jQuery这样的库之前,在不算多的前端开发中,已经完成了一些常用的函数。这之后,再接触到jQuery,有一个好处,那就是有了从实践来的比较和判断标准。每个机械工人要组装一台机器,都会需要像螺丝刀、扳手、钳子之类的工具。他可以自己从头开始做这些工具,也可以使用人家已经做好的工具,还可以继续改进这些工具。jQuery、Prototype、YUI、ExtJS,这些就像不同公司出品的各种成套工具。它们的作用可以概括为两大类:
一是将各种浏览器(包括不同版本)的API的差异封装起来,提供一个统一的接口。否则,开发人员如果要写出不限于某种特定浏览器的代码,就要掌握多种浏览器的API之间琐碎的差别。比如为某个元件绑定事件处理程序,在IE里曾经使用的方法名为attachEvent(),后来变为和Firefox相同的addEventListener()。又比如IE支持的document.all.elementName和document.links[2]的代码就不具备跨浏览器的移植性。
二是增强这个统一的开发接口。使用原始浏览器接口能做的,现在可以做得更方便;原始的JavaScript和DOM没有的却又是被希望有应该有的功能,被不断增加进来。
jQuery就是这样一个让包括笔者在内很多人觉得顺手的一个工具箱。让我们来看看这个箱子里的工具有哪些。jQuery的API文档http://api.jquery.com/就是一个很好的参考,下面的代码样例即基于该文档。
前面提到,JavaScript程序围绕的基本对象就是HTML元件。首先我们就需要获得DOM树中某些特定的HTML元件,一个Id为action1的按钮,一个Id为mainDiv的DIV里的类为Inactive的所有DIV,一个表格中的第一行,某个包含一个Id为submitBtn的按钮的名称为actionBar的DIV的父对象中的第二级DIV……开发中我们会遇到各种各样的需求,而最初DOM接口只提供了getElementById()、getElementsByName()、getElementsByTagName()等最基本的检索方法,很多情况下我们都需要应时写代码来获取目标元件。后来DOM虽然补充了querySelect()和querySelectAll(),但是在功能的丰富性和使用方便性上,比逐渐发展成熟的脚本库的选择函数仍然逊色。在API文档的选择器(Selectors)类别下列出了大量满足不同情况需要的方法,从元件的属性、内容到选择表单上的控件和根据元件的层次,不一而足(jQuery这部分的功能是直接采用属于另一个流行的JavaScript框架dojo的代码,即Sizzle脚本,这一点其实也体现出JavaScript库的同质性现象。毕竟,很多时候,完成某个功能好的方法没有那么多种。在JavaScript库这个开源进化的领域,不少脚本库或者是被淘汰,或者是相互借鉴,因而开发人员在使用不同的库时,差别并没有那么大)。按条件查询后,还可以用遍历(Traversing)分类下的方法对结果集合进行查找、增删和过滤。
举一些常见的例子:
//选择类为myclass的元件下的名称属性为basic的p元件
$(“.myclass p[name=’basic’]”);
//选择Id为sheet的div元件的直接子元件中的表格的第一行
$(“#sheet > table tr : first”);
获得Html元件之后,自然就要或是读取它的属性,或是修改它的内容。这些功能被涵括在jQuery的修改/操作(Manipulation)、属性(Attributes)、CSS、尺寸(Dimensions)和偏移(Offset)等类别下(一个方法可以属于多个类别,以说明它的不同特征,方便用户从不同的需求出发快速找到所要的成员)。用一些常见的操作做例子:
//修改类属性
$("p").removeClass("myClass").addClass("yourClass hisClass");
//读取和修改CSS属性
var color = $("#target").css('background-color'};
$("#target").css({'background-color': '#ffe', 'border-left': '5px solid #ccc'});
//读取和修改Html内容
var html = $(“#target”).html();
$(“#target”).html(“Success”);
//插入新建的元件
$(“#target”).after(“Test
”);
JavaScript最重要的编程模式就是事件。在Web应用中,我们要频繁地给Html元件添加删除事件处理程序。在处理事件的函数中,我们可能需要用到事件触发时产生的包含相关信息的参数对象,又有时我们要传递额外的信息给这些函数,更有时我们要自定义事件。所有这些,都被jQuery事件(Events)类别下的API提供了整套的解决方法。Html事件的全面知识,包括原理、传递的顺序、类型、事件参数、添加和删除响应程序等等,当然都需要专门的学习,但是这些内容并不是因jQuery产生的,jQuery只是在这些基础之上给出了简捷方便和全面的接口。所以和JavaScript语言本身的知识一样,它们是学习和掌握jQuery的预备技能,并且一旦理解,jQuery的封装就会十分易学和自然。下面只是一个最简单的样例:
//给一个按钮添加单击事件的响应程序
function demo(event) {alert(“I like ” + event.data.fruit);}
$(“#action”).on(“click”, {fruit: “banana”}, demo);
Ajax技术是现代Web应用的基石,但是浏览器的原始API相对复杂和繁琐。以最早引入XMLHttpRequest的IE浏览器为例,下面的代码显示了使用XMLHttpRequest的流程。
/*获取一个XMLHttpRequest对象,兼容IE 6和IE 7以后的版本,忽略了最初支持XMLHttpRequest的IE 5里用于创建XMLHttpRequest的ActiveX对象Microsoft.XMLHTTP。
*/
function getXMLHttpRequest()
{
if (window.XMLHttpRequest) {
return new window.XMLHttpRequest;
}
else {
try {
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
catch(ex) {
return null;
}
}
}
//定义XMLHttpRequest的响应返回时的处理函数。
function handler()
{
if (oReq.readyState == 4 /* complete */) {
if (oReq.status == 200) {
console.log(oReq.responseText);
}
}
}
//使用上面的函数,向给定地址发出一个XMLHttpRequest。
var oReq = getXMLHttpRequest();
if (oReq != null) {
oReq.open("GET", "http://localhost/test.php?name=John&location=Boston", true);
oReq.onreadystatechange = handler;
oReq.send();
}
else {
window.console.log("AJAX (XMLHTTP) not supported.");
}
我们可以看出,在上面的代码中,使用XMLHttpRequest的API的例行部分占了很大比例。如果我们的程序经常使用Ajax,当然希望会有更简洁方便的API供调用。jQuery里Ajax分类下的方法就封装了各种浏览器的原始API,提供了简明强大的接口。下面的简单直观的几行代码就是调用jQuery的Ajax接口实现类似上面代码的功能。
$.ajax({
url: " http://localhost/test.php ",
data: { name: "John", location: "Boston" }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
为了封装原始XMLHttpRequestAPI的细节和为实际开发中各种需求提供方便,jQuery的Ajax功能也包含了不少函数和参数。不过可以说对于这么完备的工具箱里,百分之八十的场景只会用到百分之二十的部分,剩下的只需作为备用,少数情况下可以参考借助。
除了上述几大类别,jQuery的开发者们还针对实践中各种有普遍性的需求,整理和提供了他们的方案。有些是很实用的对JavaScript语言的扩展,比如trim()、isNumeric()、isArray()、inArray()等;有些是jQuery对象本身的方法,比如get()、size()、noConflict()等。这些都被归类到工具(Utilities)和杂项(Miscellaneous)底下。
总结
总而言之,在了解了jQuery是什么,能做什么之后,API文档就成为最重要和最主要的学习和掌握jQuery的资料。和其他一切API文档一样,学习者只需要对它的范围和结构有认识和印象,应用中遇到模糊和不确定的时候,再来查询和参考就可以。也就是开始时浏览以获得总体了解和印象,以后随需而查,既平缓了学习曲线,又高效利用了精力和时间。相反,如果按部就班地学习,不分常用和冷门,不仅耗时,而且真到用时恐怕记忆还是不够精确,需要回头再查。