5.5 高级事件管理
使用jQuery时间方法和前面所介绍的概念,我们可以度过一段更长、更快乐的编程生活。但是,如果真的想要从jQuery的事件处理技术中得到最大的益处,那么需要了解bind()函数。
注意:如果前面一节的内容令你头疼,可以先跳转到5.6节的教程,直到你对事件处理有更多的经验。
与jQuery的click()和mouseover()这样的特定于事件的函数相比,bind()方法是处理事件的一种更加灵活的方式。它不仅允许指定一个事件以及响应该事件的一个函数,而且允许传递供事件处理函数使用的额外数据。这就允许不同的元素和事件(例如,链接上的一个click,或者图像上的一个mouseover)向相同的事件处理函数传递不同的信息,换句话说,一个函数可以根据触发了哪个事件而采取不同的响应。
bind()函数的基本格式如下:
$('#selector').bind('click',myData, functionName);
第一个参数是包含了事件名称的一个字符串(例如,click、mouseover,或者5.1.1节列出的任何其他事件)。第二个参数是想要传递给该函数的数据,要么是一个对象直接量,要么是包含对象直接量的一个变量。对象直接量(参见5.8.3节)实际上是属性名和值的一个列表:
{
firstName:'Bob',
lastName:'Smith'
}
可以像下面这样,将一个对象直接量存储到一个变量中:
var linkVar={message:'Hello from a link'};
传递给bind()的第三个参数是另一个函数,就是当事件触发的时候执行操作的那个函数。该函数可以是一个匿名函数,或者是一个命名函数,换句话说,这部分和使用一个常规jQuery事件的时候相同,参见5.2节的介绍。
注意:使用bind()函数传递数据是可选的。如果你只是想要使用bind()来附加一个事件和函数,那么可以直接省略数据变量:
$('selector').bind('click',functionName);
如下代码与它实现同样的功能:
$('selector').click(functionName);
假设你想要弹出一个警告框来响应事件,但是,想要根据触发事件的元素的不同而在警告框中显示不同的消息。做到这点的一种方法是,创建其中包含不同对象直接量的变量,然后,将这些变量发送给针对不同元素的bind()函数,如下面的例子所示:
var linkVar={message:'Hello from a link'};
var pVar={message:'Hello from a paragraph'};
function showMessage(evt){
alert(evt.data.message);
}
$('a').bind('click',linkVar, showMessage);
$('p').bind('mouseover',pVar, showMessage);
图5-5详细说明了这段代码是如何工作的。它创建了两个变量,第一行的linkVar和第二行的pVar。每个变量都包含了一个对象直接量,具有相同的属性名、消息,但是消息文本不同。函数showMessage()接收事件对象(参见5.4.3节),并且将其存储到一个名为evt的变量中。该函数运行alert()命令,显示message属性(其本身是事件对象的data属性的一个属性)。记住,message是对象直接量中定义的属性的名称。
图 5-5 jQuery的bind()函数允许传递数据给响应事件的函数。通过这种方式,可以将单个函数用于几个不同的元素(甚至是针对不用类型的事件),而允许该函数根据每个事件辅助函数来使用数据
使用bind()函数的其他方法
jQuery的bind()函数提供了很大的编程灵活性。除了前面内容中列出的技巧,它还允许把两个或多个事件绑定到同一个函数。例如,假设你编写了一个程序,当访问者单击一幅缩略图图像的时候,它使得一幅较大的图像出现在屏幕上(即成千上万的Web站点上常见的Lightbox效果,我们将会在7.4节介绍它是如何实现的)。当访问者单击页面的任意位置或者敲击键盘上的任意键的时候,你想要让较大的图像消失(如果两种选择都提供的话,你的程序对于喜欢使用键盘和鼠标的访问者都能做出响应)。做到这一点的代码如下所示:
$(document).bind('click keypress',function(){
$('#lightbox').hide();
});//end bind
关键部分是'click keypress'。通过提供多个事件名称,每个名称用一个空格隔开,我们告诉jQuery,当列表中的任何一个事件发生的时候,运行该匿名函数。在这个例子中,就是当文档上的click或keypress事件触发的时候。
此外,如果想要附加几个事件,而每个事件触发不同的行为,就不需要多次使用bind()函数。换句话说,如果想要让访问者单击一个元素的时候发生一件事情,而访问者将鼠标光标悬停到同一个元素上的时候发生另一件事情,你可能会尝试这样编写代码:
$('#theElement').bind('click',function(){
//do something interesting
});//end bind
$('#theElement').bind('mouseover',function(){
//do something else interesting
});//end bind
但是,可以通过向bind()传递一个对象直接量(参见4.8.3节)来做同样的事情,这个对象直接量包括一个事件名,后面跟着一个分号,然后是一个匿名函数。重写上面的代码,只需要调用bind()函数一次,并传递给它一个对象直接量(粗体所示):
$('#theElement').bind({
'click':function(){
//do something interesting
},//end click function
'mouseover':function(){
//do something interesting
};//end mouseover function
});//end bind
注意:除了这里所介绍的外,jQuery还提供了其他的方式将事件附加到元素中。特别是,当你想要将一个事件附加给一个元素,而该元素是在页面加载之后才添加到页面上的(也就是说,这个元素要么是通过JavaScript编程添加到页面上的,要么是使用本书第四部分所介绍的Ajax技术下载到页面上的),这时候,delegate()函数很适用。你可以通过13.5节了解delegate()函数的相关内容。