《jQuery实战(第2版)》试读:第一章

jQuery基础 本章内容 为什么使用jQuery 不唐突的JavaScript的含义 jQuery的基本原理和概念 结合其他JavaScript库使用jQuery JavaScript从诞生那天起就被很多Web开发人员嘲笑为“玩具”语言,然而在过去的几年时间里,人们逐渐对高交互性的下一代Web应用(也被称为关注富互联网应用或者基于DOM的脚本应用)以及Ajax技术产生了热情,从而使JavaScript又重获关注。由于客户端开发人员已经抛弃剪切和粘贴JavaScript的开发方式,转而使用方便快捷、功能完善的JavaScript库,因此这门语言也得到了长足的快速发展。这些库彻底解决了跨浏览器问题,并提供了新颖的、改进了的Web开发模式。 作为一个相对年轻的JavaScript库,jQuery以迅雷不及掩耳之势席卷了整个Web开发社区,很快赢得了几家大公司的支持并被应用于其关键的产品中。jQuery的一些典型用户包括IBM、Netflix、Amazon、Dell、Best Buy、Twitter美国银行以及很多其他的知名企业。微软甚至把jQuery和Visual Studio工具一块发布,而诺基亚则在所有的手机平台以及WRT(Web Runtime Component)上使用jQuery。 这些都是jQuery足以炫耀的资本! 和其他更加关注智能化的JavaScript工具包不同,jQuery的目标是改变Web开发人员创建高交互性页面的方式。设计者无需花费时间纠缠JavaScript复杂的高级特性,而是使用现有的知识比如CSS(Cascading Style Sheets,层叠样式表)、HTML(Hypertext Markup Language,超文本标记语言)、XHTML(Extensible Hypertext Markup Language,扩展的超文本标记语言)以及原生的JavaScript直接操作页面元素,从而实现快速开发。 本书中,我们会深入学习jQuery为高交互性Web应用程序开发者提供的功能。下面来探索jQuery为Web开发盛宴带来的实实在在的好处吧。 你可以从jQuery网站(http://jquery.com/)获取最新版本的jQuery。安装jQuery相当简单,只需将它放在应用程序目录并在页面中使用HTML标签<script>来包含它,就像下面这样: 本书中使用的jQuery版本可以从下载的示例代码中找到(http://www.manning.com/bibeault2)。 1.1 用少量代码实现丰富的功能 如果你曾经尝试为页面添加一些动态的功能,那么你就会发现实现的模式经常是相同的,首先选择一个元素(或者一组元素),然后以某种方式操作这些元素。你可以显示或隐藏元素,给元素添加CSS类,让元素动起来或者改变元素的特性。 使用原始的JavaScript完成这些任务中的任何一个,都需要数十行的代码,jQuery的开发者们专门为此创建了jQuery库来简化这些常见任务。例如,有过处理单选按钮分组经验的开发人员都知道,找出分组中哪个元素被选中并获取它的value特性是非常乏味的;首先需要找出单选按钮分组,其次获取由这些单选按钮元素组成的数组并逐个遍历,找出哪个元素拥有checked特性,最后获取此元素的value特性。 过去人们通过如下代码来实现: 而jQuery只需要一行代码就能实现相同的功能: 如果这段代码看起来有点神秘请不用担心。很快你就能搞懂它的工作原理,并创建出简洁而强大的jQuery代码来武装你的页面。下面简单看一下这个强大的代码片段是如何工作的。 首先,找出所有name特性值为someRadioGroup的元素(别忘记单选按钮分组是由一系列拥有相同名称的单选按钮元素组成的),然后过滤这个集合从而得到处于checked状态的那个单选按钮,并获取它的value特性。(只可能有一个符合条件的元素,因为浏览器只允许选中同一分组中的一项单选按钮。) 这条jQuery语句的真正威力来自选择器,它是一个识别页面元素的表达式。它帮助我们轻松找到并获取需要的元素。在上面的例子中,就是单选按钮分组中被选中的元素。 如果你还没有下载示例代码,现在就去下载吧。下载链接就在本书的官方网站:http://www. manning.com/bibeault2(别忘记链接中最后的字符2)。把下载的代码解压缩到任意文件夹之后,可以打开单独的文件,也可以通过根目录下的索引页(index.html)访问任意文件。 在浏览器中打开文件chapter1/radio.group.html,如图1-1所示,这个示例展示了如何使用jQuery获取单选按钮分组中被选中的元素。 这个简单的例子应该可以使你信服,jQuery能够以轻松的方式创建高度交互的下一代Web应用程序。随着对本书各章的学习,我们将会逐渐揭开jQuery的神秘面纱,让你全面感受jQuery驾驭页面的强大能力。 我们很快就会学习如何创建jQuery选择器,正是它使得本例如此简单,但是先来了解一下jQuery作者对于如何在页面上最有效地使用JavaScript有什么样的想法。 图1-1 使用一条jQuery表达式轻松获取被选中的单选按钮 1.2 不唐突的JavaScript 记得在CSS出现之前糟糕的往日吗?那时我们不得不在HTML页面中混合使用样式标记和文档结构标记。任何一个网页开发人员,无论从事开发的时间长短,都一定会对这种陈旧的开发方式深恶痛绝。 CSS的出现让Web开发人员可以将样式信息从文档结构中分离出来,而且摒弃了老式的<font>等标签 。将样式从文档中分离出来不仅有利于页面的维护,而且能够使我们只需通过切换样式表就能完成页面的换肤功能。 很少有人愿意再将样式嵌入HTML元素中,然而下面的代码却依然很常见。 可以清楚地看到,这个按钮的样式(包括按钮标题的字体)不是通过废弃的<font>标签或者其他样式标签设置的,而是通过某种应用到页面上的CSS规则(没有列出)设置的。尽管这里的声明没有把样式和结构混合在一起,但是它把单击按钮时需要执行的JavaScript脚本(本例中,脚本把id值为xyz的DOM元素的颜色改为红色)放在了按钮标签的onclick特性中,这使得行为和结构混合在了一起。 下面来看看怎么改进这种情况。 1.2.1 行为和结构分离 就像在HTML文档中应该把样式从结构中分离出来一样,我们有同样的理由把行为从结构中分离出来。 理想情况下,HTML页面应该按照图1-2的方式来组织结构、样式和行为3部分,每一部分都有属于自己的位置。 图1-2 将结构、样式和行为整齐地放置在页面的不同部分,最大限度地确保了可读性和可维护性 这种策略被称为不唐突的JavaScript,是由jQuery的开发者引入公众视野的,已经扎根于所有主要的JavaScript类库中,它能帮助页面开发者在页面中实现这种有效的分离。随着jQuery对这一概念的推广,jQuery的核心也在逐步优化以便更加容易地生成不唐突的JavaScript代码。不唐突的JavaScript认为,任何存在于HTML页面<body>内部的JavaScript代码都是错误的,这些错误代码或者存在于HTML元素特性(比如onclick特性)中,或者存在于页面<body>脚本块中。 你或许会问:“如果不使用onclick特性,如何为按钮添加行为呢?”考虑下面按钮元素的变化: 这就简单多了!但你会发现,现在的按钮不能做任何事情了。你可以一直不停地单击它,但是没有任何反应。 下面就来解决这个问题。 1.2.2 分离脚本 我们可以将按钮的行为移到<head>标签里的脚本块中,而不是把它们写在标记里,这样脚本就被移出了<body>之外,如下所示: 我们把脚本放在页面的onload处理函数中,并将一个内联函数赋给按钮元素的onclick特性。 之所以将这段脚本放在onload处理函数中(而不是直接放在内联代码块中),是因为我们要确保在使用按钮元素之前,它已经存在于页面中了。(在1.3.3节中,我们将看到jQuery提供了更好的地方来放置这些代码。) 注意 出于对性能的考虑,也可以把脚本块放在文档主体的底部,不过现代浏览器的速度都已经很快了,这么做的性能差异可以忽略不计。这里重点强调的概念是避免在结构性的元素中嵌入描述行为的代码。 如果本例的代码看起来不太好理解(比如函数字面值与内联函数的概念),也不要担心!为了帮助你更高效地使用jQuery,本书附录包含了你需要掌握的重要JavaScript概念。本章的剩余部分将探讨jQuery如何帮助我们更加轻松和快速地编写上述代码,并保持代码的通用性。 不唐突的JavaScript是一项强大的编程技术,为Web应用开发引入了清晰的职责划分,但这样做也是有代价的。你可能已经注意到,与直接在按钮标记中放置脚本相比,不唐突的JavaScript需要编写更多行代码来实现同样的功能。不唐突的JavaScript可能会增加代码的行数,并且它还需要客户端脚本遵守一些规则并且应用良好的编码模式。 但这未尝不是一件好事,它能够促使我们以编写服务器端代码的严谨态度来编写客户端代码。但那需要做很多额外的工作——如果没有jQuery的话。 如前所述,jQuery团队尤其注重以简单和愉快的方式在页面上使用不唐突的JavaScript,而无需付出大量精力编写大段代码。我们将发现,有效利用jQuery能够有助于用更少代码实现更多的功能。 事不宜迟,下面就开始介绍如何在jQuery的帮助下轻松地为页面添加丰富的功能。 1.3 jQuery基础 jQuery主要关注从HTML页面上获取元素并对它们进行操作,这是jQuery的核心。如果你熟悉CSS,那么对选择器的强大功能一定印象深刻,它通过类型、特性或在文档中的位置来描述元素集合。有了jQuery,你就能够利用现有知识发挥选择器的强大威力,极大地简化JavaScript代码。 jQuery的首要目标就是确保在所有主要浏览器下都能流畅地运行代码。很多JavaScript难题(比如等待页面加载完毕后才能执行页面操作)都已经被jQuery轻松地解决了。 如果需要更多的功能,jQuery还通过插件提供了简单而强大的内置方法,以扩展其现有的功能。很多jQuery新手发现他们在学习的第一天就能自己编写插件了。 下面开始学习如何借助CSS的现有知识来生成强大而简洁的代码。 1.3.1 jQuery包装器 当为了使设计和内容分离而把CSS引入Web技术的时候,需要以某种方法从外部样式表中引用页面中的元素组。这种方法就是选择器,它可以根据元素的类型、特性或者元素在HTML文档中的位置来精确地描述元素。 熟悉XML的开发者可能会联想到使用XPath选择XML文档中的元素。CSS选择器使用了同样强大的概念,但为了适用于HTML页面而做了优化,从而更加简洁且更易理解。 比如,选择器 引用位于<p>元素内的所有超链接(<a>元素)集合。jQuery使用相同的选择器,不仅支持常用的CSS选择器,而且支持一些没有被所有浏览器完全实现的选择器,甚至包括CSS3中定义的一些强大的选择器。 要选择一组元素,只需使用如下的简单语法将选择器传递给jQuery函数。 或者 可能一开始你会觉得$()符号有点儿奇怪,不过大部分jQuery用户会很快喜欢上这种简洁的语法。比如,选择位于<p>元素内的一组链接,可以使用如下代码: $()函数(jQuery()函数的别名)返回特殊的JavaScript对象,它包含与选择器相匹配的DOM元素数组,这个数组中的元素是按照在文档中的顺序排列的。这个对象拥有大量有用的预定义方法,可作用于已收集的元素集合。 在编程用语中,这种构造方法称为包装器(wrapper),因为它包装了收集到的元素并添加了扩展功能。我们使用术语jQuery包装器或者包装集,来指这些可以通过jQuery定义的方法操作的含有匹配元素的集合。 假如想隐藏所有类名为notLongForThisWorld的<div>元素,就可以使用以下jQuery代码: 这样的方法有很多,通常称为jQuery包装器方法,它们有一个特点——当执行完毕后(比如隐藏操作)会返回相同的一组元素,以便为另一个操作做准备。例如,假设除了隐藏这些元素,我们还想为每一个元素增加一个新的类removed。可以这样写: 这些jQuery作用链可以无限延续。jQuery作用链绵延数十种方法的示例也不罕见。因为每一种方法都作用在与最初的选择器相匹配的元素集上,所以没有必要遍历元素集。jQuery已经为我们在后台完成了这一切! 尽管选择的对象组通过一个高度复杂的JavaScript对象来呈现,但是如果有必要的话,也可以把它当做普通的元素数组来对待。因此,下面两段代码的结果相同: 和 由于使用了ID选择器,因此选择器只能匹配一个元素。第一个示例使用jQuery的html()方法,用一些HTML标记替换DOM元素的内容。第二个示例使用jQuery获取元素数组,通过数组下标0选择第一个元素,然后将值赋给一个常见的JavaScript属性innerHTML来替换内容。 如果想让匹配多个元素的选择器达到相同的效果,下面两个代码片段将会产生相同的结果(但第二个不是jQuery推荐的编程方式)。 和 随着逻辑逐渐复杂,使用jQuery作用链可以不用改变预期结果而减少代码行数。此外,jQuery不仅支持我们已经知道并且喜爱的选择器,而且还支持更高级的选择器(作为CSS规范定义的一部分),甚至是一些自定义选择器。 表1-1给出了一些示例。 表1-1 选择器示例 选 择 器 结  果 $("p:even") 选择所有偶数行的<p>元素 $("tr:nth-child(1)") 选择每个表格的第一行元素 $("body > div") 选择作为<body>直接子节点的<div>元素 $("a[href$= 'pdf ']") 选择链接到PDF文件的超链接元素 $("body > div:has(a)") 选择作为<body>直接子节点的、包含超链接(<a>)的<div>元素 这太强大了! 你可以利用已经掌握的CSS知识来快速入门并提高,然后学习jQuery支持的更高级选择器。我们会在第2章详细介绍jQuery选择器,你也可以在jQuery站点找到选择器的完整列表http://docs.jquery.com/Selectors。 选择DOM元素来进行操作是Web开发中的常见需求,但有些需求和DOM元素毫无关系。下面粗略考察除了元素操作之处jQuery还提供了哪些功能。 1.3.2 实用函数 尽管包装将要操作的元素是jQuery $()函数最常见用法之一,但却并不是它的唯一职责。$()函数的另一个职责是作为一些通用实用函数集的命名空间前缀。由于以选择器为参数来调用$()生成的jQuery包装器赋予了页面开发者如此强大的力量,以至于大部分的页面开发者很少会用到其中的一些实用函数。实际上,直到第6章我们才会详细地学习大部分实用函数以便为编写jQuery插件做准备。不过下面的几节将会用到一些实用函数,因此先来简单了解一下。 这些函数的符号初看起来可能会有点奇怪。比如,用来去除字符串前后空格的实用函数,其调用形式如下: 如果你觉得$.前缀有点儿怪异,就记住$是JavaScript中的标识符,和其他的标识符没有什么不同。使用标识符jQuery(而不用别名$)来调用这个函数,可能看起来就没那么奇怪了如: 现在可以清楚地看到,trim()仅仅是jQuery(或它的别名$)命名空间下的一个函数。 注意 尽管这些元素在jQuery文档中被称为实用函数,但它们实际上是$()函数的方法 (是的,在JavaScript中函数也可以有自己的方法)。为了不和jQuery在线文档产生术语上的冲突,我们撇开这些技术差异,使用实用函数来描述这些方法。 我们会在1.3.5节中学习一个用来帮助扩展jQuery的实用函数,然后在1.3.6节中学习另一个可以让jQuery和其他客户端库共存的实用函数。但首先要看一下jQuery 的$()函数的另一个重要职责。 1.3.3 文档就绪处理程序 当遵循不唐突的JavaScript原则时,行为就从结构中分离出来了,因此我们要在文档标记外部执行对页面元素的操作。为了达到这一目的,我们需要一种在页面DOM元素完全渲染后再执行操作的方法。在“单选按钮分组”示例中,必须在整个页面主体加载完毕后再应用行为。 传统上,window实例的onload处理程序就是为了实现上述目的,该程序在整个页面加载完毕后执行代码。其典型的语法如下: 这样就能在文档完全加载后执行定义的代码。然而,浏览器会延迟执行onload的代码,不仅是在创建DOM树之后,而且在所有外部资源全部加载完毕,并且整个页面在浏览器窗口中显示完毕之后。这些资源不仅包括图片资源,而且包括嵌入在页面上的QuickTime和Flash视频资源,如今这类资源会越来越多。结果是,从首次浏览页面到onload脚本执行完毕,访问者将会经历一段严重的延迟。 更糟糕的是,如果图片或者其他资源需要很长时间来加载,则访问者就需要等待图片加载完成后才能使用丰富的页面行为。这会使不唐突的JavaScript的提议,在很多实际案例中遭遇滑铁卢。 更好的方式是,在执行脚本以便应用丰富行为之前,只需要等待文档结构被完全解析并且浏览器已经把HTML转化为DOM树。跨浏览器完成这个任务略有困难,但是jQuery提供了一个简单的方式:在DOM树(而不是外部资源)加载完毕之后立即触发脚本的执行。正式的语法结构(使用前面的隐藏元素的例子)如下所示: 首先,使用jQuery()函数包装document对象,然后调用ready()方法并传递一个在文档就绪时执行的函数。 上述语法称为正式语法是有原因的,因为还有一个更常用的简写形式,如下所示: 通过传递一个函数给jQuery()或者$(),我们通知浏览器直到DOM被完全加载完毕(仅仅是DOM)后再执行此段代码。更棒的是,可以在一个HTML文档中多次调用此函数,浏览器会按照它们在页面中声明的顺序依次调用这些函数。与此相反,window的onload机制只允许指定一个函数。如果包含的任何第三方代码出于自身考虑使用onload机制(并非最佳方法),那么这个限制可能导致难以发现的问题。 以上就是$()函数的另一种用法,现在看看它还能做什么。 1.3.4 创建DOM元素 目前为止可以看到,jQuery的开发者通过赋予$()函数(仅仅是jQuery()的别名)更多的职责,来避免向JavaScript命名空间引入大量的全局名称。不过,$()函数还有一个职责需要探讨。 可以通过向$()函数传递一个包含HTML标记的字符串动态地创建DOM元素。例如,可以创建一个新的段落元素,如下所示: 但是凭空创建一个DOM元素(或者具有层级的元素)用处不大。通常在按照这种方式创建有层级的元素之后,会接着应用jQuery的DOM操作函数。下面探讨代码清单1-1中的示例。 代码清单1-1 动态创建HTML元素 这个示例在文档主体中创建了一个名为followMe 的HTML段落。在<head>中的脚本元素里创建了一个就绪处理器 ,用来把一个新创建的段落插入到DOM树中那个已有元素的后面,语法如下: 结果如图1-3所示。 图1-3 动态创建和插入元素通常需要多行代码,不过jQuery可以使用一行代码轻松搞定 我们会在第3章中详细地考察全套的DOM操作函数,jQuery提供了许多操作DOM的方式,以创建任何想要的HTML结构。 在学习了jQuery的基本语法之后,下面将学习jQuery库的最强大的一个功能。 1.3.5 扩展jQuery jQuery包装器函数提供了大量有用的方法,可以在页面上反复使用。但是没有任何一个库可以满足用户的所有需求。试图满足所有需求的库是不合理的,这可能会导致一大堆庞大的、臃肿的、包含很少可用功能的代码,这只会把事情搞砸。 由于认识到这个概念的重要性,所以jQuery开发者努力提取大部分页面开发者都需要的功能,只在核心库包含这些功能。jQuery的开发者还意识到每个页面开发者都有个性化需求,因此将jQuery设计成可以很容易通过附加功能来扩展的库。 可以编写一些函数来填补任何空白,但是一旦习惯jQuery的代码风格,我们会发现使用传统的方式来扩展功能是超级乏味的。可以使用jQuery提供的强大功能对其进行扩展,特别是在元素选择领域。 下面看一个具体的例子:jQuery没有任何预定义函数来禁用一组表单元素。如果在应用中大量使用表单,就会发现下面的代码非常便利: 幸运的是,通过扩展在调用$()时返回的包装器,jQuery从设计上保证了其方法集很容易就得到扩展。下面请看如何通过创建一个新的disabled()函数实现上述功能的基本用法: 这里引入了很多新的语法,但不要过于担心。只要继续学习以下几章,你将会很熟悉这些语法并会频繁使用这些基本的惯用语法。 首先,$.fn.disable表示使用disabled方法扩展$包装器。在函数内部,this关键字指向将要操作的DOM元素集合。 然后,通过调用包装器上的each()方法遍历每一个匹配的元素。我们会在第3章详细探讨这种方法及其类似方法。在传入each()的迭代器函数内,this是对当前遍历的特定DOM元素的引用。不要被嵌套函数内this指向不同对象所迷惑。多写一些扩展函数后你就会发现,this指向当前函数内的不同对象是相当自然的事情。(附录中也有对JavaScript中this关键字概念的解释。) 检查每一个元素是否具有disabled特性,如果有,就把该特性设为true。返回each()方法的执行结果(即包装器),从而使新创建的disabled()方法支持链式操作(正如许多jQuery原生方法那样)。可以这样编写代码: 从页面代码的角度看,新方法disabled()仿佛内置在jQuery库一样!这门技术格外强大,以至于很多jQuery新手在使用jQuery库的初期就能创建一些小的扩展了。 此外,jQuery的企业级用户已经为jQuery扩展了多套有用的功能(也被称为插件)。我们会在第7章中详细介绍这种扩展jQuery的方法。 测试存在性 你可能见过这个用来判断一个项目是否存在的常见用法: 这里的逻辑是,如果item不存在,则条件表达式将等于false。 尽管这在大部分的情况下都能正常工作,但jQuery的开发者还是认为这过于宽松和不严谨,推荐在$.fn.disable示例中使用更加明确的测试方法: 这个表达式会正确地测试null或者undefined值。 访问jQuery在线文档即可查看jQuery团队推荐的各种代码风格的完整列表:http:// docs.jquery.com/JQuery_Core_Style_Guidelines。 在深入学习如何使用jQuery为页面增加活力之前,你可能想知道能否同时使用jQuery和Prototype,或者其他同样使用$缩略符的库。下一节会揭示这个问题的答案。 1.3.6 jQuery与其他库共存 尽管jQuery所提供的功能强大的工具集足以满足大部分的需求,但有时还会遇到一种页面需要引入多个JavaScript库的情况。这种情况之所以会产生,可能是因为我们把一个使用了其他库的应用转换为使用jQuery库,也可能是我们想在页面中同时使用jQuery和其他库。 jQuery开发团队明确表示,他们关注的是如何满足jQuery社区用户的需求,而非排挤其他库,因此提供了允许jQuery和其他库共存的方法。 首先,他们遵循最佳实践原则,避免引入大量的标识符而污染全局命名空间。因为大量的标识符不仅可能会与其他库冲突,也可能会与我们想在页面上使用的名字冲突。标识符jQuery和其别名$是jQuery为全局命名空间引入的唯一变量。在1.3.2节曾提到的作为jQuery命名空间一部分而定义的实用函数,就是出于这方面考虑的最好示例。 尽管其他库定义一个名为jQuery的全局标识符的可能性不大,但是在下面这种特殊情况下, jQuery的开发者出于方便性考虑使用$作为jQuery的别名,却会带来麻烦。其他JavaScript库(比如著名的Prototype库)出于自身考虑会使用$名称。并且$名称是Prototype库运行的关键,这就产生了严重的冲突。 深思熟虑的jQuery作者通过一个名为noConflict()的实用函数来消除这种冲突。在引入会产生冲突的库后,调用 就可以保留$标识符给其他库使用了。 我们会在第7章详细阐述引入此实用函数后代码的细微差别。 1.4 小结 在本章对jQuery的快速介绍中,我们学习了许多内容,为深入探索使用jQuery轻松、快速地开发下一代Web应用程序做好了准备。 jQuery通常对任何需要执行操作(除了那些微不足道的JavaScript操作)的页面都非常有用,而且也高度关注如何帮助页面开发者在页面中使用不唐突的JavaScript。采用jQuery的解决方案,把行为从结构中分离出来,正如CSS把样式从结构中分离出来一样,它能使我们更好地组织页面,增加代码的灵活性。 尽管事实上jQuery仅仅向JavaScript命名空间引入了两个新的命名(jQuery函数和其别名$),它却通过使jQuery函数高度多功能化,以及根据传入的参数调整执行的操作来提供大量的实用功能。 jQuery()有如下用途: 通过包装器方法选择和包装将要操作的DOM元素; 为全局实用函数提供命名空间; 从HTML标记创建DOM元素; 创建在DOM就绪后执行的代码。 jQuery在页面上表现出色,它不仅尽量减少了对全局JavaScript命名空间的占用,而且提供了官方方法,以尽可能减少当冲突依然存在时对命名空间的占用问题,也就是当页面上另一个库(比如Protorype)也要求使用$名称的时候。jQuery在用户友好方面做得不错吧! 接下来的几章,我们将探索jQuery为富因特网应用开发人员提供的全部功能。下面即将开始学习之旅,下一章我们学习使用jQuery选择器快速、简单地找出那些需要操作的元素。

>jQuery实战(第2版)

jQuery实战(第2版)
作者: [美]Bear Bibeault, [美]Yehuda Katz
原作名: jQuery in Action
isbn: 7115274576
书名: jQuery实战(第2版)
页数: 394
译者: 三生石上
定价: 69.00元
出版社: 人民邮电出版社
装帧: 平装
出版年: 2012-3