在 Forge - jQuery
JavaScript 已经变得有些令人惊讶地成为最热门的编程语言之一。问题不是 Web 开发人员是否需要了解 JavaScript,而是他们在使用 JavaScript 时应该使用哪个库。这是因为核心 JavaScript 语言有点粗糙,在不同的浏览器和平台之间存在不兼容性。其他跨平台浏览器差异在某种程度上加剧了这种情况,例如事件处理的不同实现方式,这可能会使开发人员难以处理此类问题。
在过去的几年中,我的大部分 Web 开发工作都是使用 Ruby 语言,特别是 Ruby on Rails 框架。Rails 自带一个高质量的 JavaScript 库,名为 Prototype,我写过几篇专栏文章描述如何使用 Prototype,以及构建在其语言改进之上的 Scriptaculous 效果库。
Prototype 不会消失。但是,在过去的几个月中,我注意到 Rails 社区以及其他开发人员社区对 jQuery 产生了越来越浓厚的兴趣,jQuery 是另一个高质量的开源 JavaScript 工具包。最重要的是,jQuery 被微软选为官方 JavaScript 库供其开发人员使用。jQuery 还有大量现成的插件,包括许多提供用户界面功能的插件。而且,当我开始探索 jQuery 时,我开始认为它的粉丝们有道理,我甚至开始考虑将我的一些工作从 Prototype 转移到 jQuery。
是什么让 jQuery 如此特别和与众不同?它提供了什么?以及,您如何将其集成到您的应用程序中?本月,我尝试回答所有这些问题,因为我们将探索 jQuery 的一些基本功能。下个月,我们将看看 jQuery 提供的一些 UI 小部件,以美化我们的网站并使其更实用。
jQuery 最初于 2006 年发布,基于 John Resig 自 2005 年 8 月以来所做的初步工作,作为一个简单的 JavaScript 库,它将使开发 Web 应用程序更加方便。随着时间的推移,它已经发展到包括许多贡献者。Resig 本人撰写了两本关于 JavaScript 的书,现在在 Mozilla 公司担任 JavaScript 布道师。
如果您以前使用过 Prototype,您不会感到惊讶的是,$() 不仅是 JavaScript 中的合法函数名称,而且它在 jQuery 中也被广泛使用。但是,$() 在 jQuery 中的工作方式与在 Prototype 中不同。在 Prototype 中,您可以说
$('foo') // Prototype
来获取 id 属性为 foo 和 bar 的元素。Prototype 的 $() 的参数数量决定了它是返回单个值还是数组,以及返回的数组包含多少个元素。
Prototype 还允许您使用 CSS 选择器(和各种伪选择器),使用 $$() 函数来检索项目。例如
$$('tr.even') // Prototype
返回一个数组(并且始终是一个数组,即使它只匹配单个对象),其中包含所有类为 even 的 tr 标签。
嗯,jQuery 的工作方式类似,只是它只有一个函数 $()。该函数足够智能,可以根据您给它的单个 CSS 样式选择器来识别您想要什么。(是的,您可能只指定一个选择器。)但是,id 属性需要以 # 字符开头,这与 CSS 中的情况相同。因此,您可以说
$('#foo') // jQuery
并且没有任何这样的项目,jQuery 会愉快地返回与该查询匹配的元素集——一个空集。
乍一看这可能有点奇怪。毕竟,您不需要预先知道您将获得多少结果,甚至是否会有结果吗?否则,您怎么知道是在返回的一个元素上调用函数,还是迭代一组元素并在每个元素上调用函数?
一旦您理解了 jQuery 的许多函数都使用所谓的隐式迭代来操作,事情就变得更有意义了。也就是说,您可以说
$('p').show();
jQuery 将抓取文档中的所有段落并显示它们。如果没有段落,则什么也不会发生。如果只有一个段落匹配,则会显示它(如果它尚未显示)。您不必使用 each() 循环遍历每个元素的想法非常强大,并且在 jQuery 代码中经常重复出现。
同样强大的是,大多数 jQuery 方法都返回它们被传递的同一集合。例如,如果我们想要显示所有段落,然后将它们的背景颜色设置为红色,我们可以说
$('p').show().css({'background-color': '#f00'});
以这种方式链接方法在 jQuery 中非常典型,并且有助于使代码更具可读性和简洁性。
当我第一次看到 jQuery 使用 $() 的方式时,我意识到这意味着我可能无法在同一个程序中同时使用 jQuery 和 Prototype,因为在两个系统中 $() 之间会存在命名空间冲突。但是,jQuery 的作者考虑了这个问题,并且可以加载 jQuery 而不激活 $(),从而可以在同一个文件中混合使用 jQuery 和 Prototype
jQuery.noConflict();
虽然我不确定计划混合使用 JavaScript 库是否是一个好主意,但有时您可能想要使用特定的效果或小部件,例如,YUI 中可用,但 jQuery 中不可用。
像许多其他 JavaScript 库一样,jQuery 自带一组可以在页面上使用的视觉效果。我们已经看到了 show 和 hide 的提及,尽管这些方法中的每一个也可以接受一个参数(slow、normal 或 fast,或一个整数),指示效果应该运行的速度
$('p').show('slow').css({'background-color': '#f00'});
类似地,您可以让元素通过滑动(slideUp 和 slideDown)或淡入淡出(FadeIn 和 FadeOut)来隐藏和显示自身。而且,当然,您始终可以修改一个或多个 CSS 属性,正如我们在前面的示例中看到的那样,覆盖它们的原始设置。
在 jQuery 中设置事件处理程序很容易。例如,如果您希望在有人单击 id 属性为 mybutton 的按钮时弹出一个警报,您可以编写
$('#mybutton').bind('click', function() { alert("Hello, there!"); });
因为将事件处理程序绑定到按钮的单击事件非常常见,所以您可以将其缩短为
$('#mybutton').click(function() { alert("Hello, there!"); });
问题是,我们将事件处理程序放在哪里?我们不能将其放在文档的 <head> 中,因为 <body>(按钮可能包含在其中)尚未定义和可用。我们可以将其分配给 DOM 处理程序,但这存在一些问题。jQuery 方法既不引人注目(正如现代 JavaScript 应该的那样),又有效且跨浏览器兼容。我们注册一个事件处理程序,用于在文档准备就绪时执行,然后将我们想要的任何事件处理程序放在那里
$(document).ready(function() { $('#mybutton').click(function() { alert("Hello, there!"); }); }
如果您将其放在 HTML 文件的 <head> 中,jQuery 将在文档准备就绪时执行该函数。这意味着在为用户呈现 HTML 时,所有事件处理程序都将到位。调用$(document).ready()包含站点的关键 JavaScript 调用代码并不少见,其中长而复杂的函数放在外部库中。
像其他 JavaScript 库一样,jQuery 还为 AJAX(幕后 HTTP)请求提供内置支持。例如,我们可以使其单击按钮向服务器发送 HTTP 请求,抓取返回的 HTML 代码段,然后将该代码段放入用户的浏览器窗口中。为此,我们需要一个 HTML 文件
<html> <head> <link rel="stylesheet" type="text/css" media="screen" href="test.css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> // JavaScript code here $(document).ready(function() { $('#mybutton').click(function() { $('#message-paragraph').load('blah.html'); }); }); </script> </head> <body> <h1>Test page</h1> <p id="message-paragraph">This is a paragraph</p> <p><input type="button" id="mybutton" value="Button" /></p> </body> </html>
在该文件的头部,我们对 $(document).ready 进行了标准调用,它将一个处理程序分配给页面底部按钮的 click 事件,该按钮的 id 属性为 mybutton。该函数非常简单,它告诉段落 (message-paragraph) 从与当前页面相同的来源(即服务器)加载文件 blah.html。浏览器在后台异步检索文件,允许用户在检索 blah.html 的内容并将其粘贴到相应的段落中时执行其他操作。
上面演示了 jQuery 可以从外部文件检索 HTML。但是,jQuery 可以做更多的事情,不仅可以检索 HTML,还可以通过网络检索 XML 和 JSON(JavaScript 对象表示法),然后对其进行解析。我们甚至可以加载 JavaScript 文件并执行它
<html> <head> <link rel="stylesheet" type="text/css" media="screen" href="test.css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> // JavaScript code here $(document).ready(function() { $('#mybutton').click(function() { $.getScript('blah.js'); }); }); </script> </head> <body> <h1>Test page</h1> <p id="message-paragraph">This is a paragraph</p> <p><input type="button" id="mybutton" value="Button" /></p> </body> </html>
然后,我创建 blah.js
$('#message-paragraph').html("<h1>Boo!</h1>");
换句话说,我已经将功能从一个文件拆分到两个不同的文件中。不同之处在于,加载的文件被视为程序并被执行。因此,当我单击按钮时,jQuery 会加载 blah.js 的内容,然后修改段落。
正如我希望您所看到的,使用 jQuery 进行 JavaScript 编程相当容易和直接,它使我们能够快速而优雅地完成许多事情。下个月,我们将继续研究 jQuery,检查其插件架构和 jQuery UI 库中的一些小部件。
资源
jQuery 从网站 www.jquery.com 分发。该网站不仅提供软件下载,还提供文档、教程以及许多 jQuery 作者使用的各种库和工具的链接。
我最近收到了两本关于 jQuery 的书,我都觉得非常好。Packt Press 出版的 Learning jQuery 由 Jonathan Chaffer 和 Karl Sweebber 撰写,非常适合已经有另一种语言(甚至可能是 JavaScript)经验的 Web 开发人员。它回顾了 JavaScript 程序员可以使用 jQuery 完成的许多不同类型的功能。
一本更侧重于基础知识的新书是 David Sawyer McFarland 撰写的 JavaScript: The Missing Manual,由 Pogue Press 和 O'Reilly Media 出版。对于 JavaScript 初学者来说,这是一本好书,它在许多示例中使用了 jQuery,尤其是在本书的后半部分。
Reuven M. Lerner 是一位长期的 Web/数据库开发人员和顾问,是西北大学学习科学博士候选人,研究在线学习社区。在芝加哥地区生活四年后,他最近(与他的妻子和三个孩子)返回他们在以色列莫迪因的家。