从零开始学习jQuery (5) 事件与事件对象

从零开始学习jQuery (五) 事件与事件对象一.摘要事件是脚本编程的灵魂. 所以本章内容也是jQuery学习的重点

从零开始学习jQuery (五) 事件与事件对象
一.摘要

事件是脚本编程的灵魂. 所以本章内容也是jQuery学习的重点. 本文将对jQuery中的事件处理以及事件对象进行详细的讲解.?

?二.前言

本篇文章是至今为止本系列内容最多的一篇, 足以可见其重要性.? 大家反映要多列举示例. 我会在时间允许的情况下尽量多列举示例. 真正的投入生产使用的实例暂时还无法加入到文章中, 但是可能最后我会列举一些作品供大家借鉴. 另外本人水平有限, 因为我不是UI设计师. 文章可能有错误的地方, 希望大家帮忙指出, 一起学习一起进步. 在技术的世界里我们是没有任何利益瓜葛. 希望大家都抱着彼此鼓励的心态, 对于回复中的激进评论我也都会考虑, 但是希望能够彼此尊重, 保护博客园这片程序员的净土!

?

三.事件与事件对象

曾经在我的 "Javascript公共脚本库系列(二): 添加事件多播委托的方法" 和 "Javascript公共脚本库系列(三): 格式化事件对象/事件对象详解" 两篇文章中,? 曾讲解过javascript中的事件和事件对象.

首先看一下我们经常使用的添加事件的方式:

} ).trigger("click", ["foo", "bar"]);

triggerHandler( event, [data] )这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作.如果你对一个focus事件执行了 .triggerHandler() ,浏览器默认动作将不会被触发,只会触发你绑定的动作:

$("#old").click(function(){
? $("input").trigger("focus");
});
$("#new").click(function(){
? $("input").triggerHandler("focus");
});
$("input").focus(function(){?? $("<span>Focused!</span>").appendTo("body").fadeOut(1000); });

unbind( type, fn )bind()的反向操作,从每一个匹配的元素中删除绑定的事件。

如果没有参数,则删除所有绑定的事件。

你可以将你用bind()注册的自定义事件取消绑定。

如果提供了事件类型作为参数,则只删除该类型的绑定事件。

如果把在绑定时传递的处理函数作为第二个参数,则只有这个特定的事件处理函数会被删除。

把所有段落的所有事件取消绑定:
$("p").unbind()

将段落的click事件取消绑定:
$("p").unbind( "click" )

删除特定函数的绑定,将函数作为第二个参数传入:

var foo = function () {
? // 处理某个事件的代码
};
$("p").bind("click", foo); // ... 当点击段落的时候会触发 foo
$("p").unbind("click", foo); // ... 再也不会被触发 foo

?

五.常用事件函数举例1.bind( type, [data], fn ) 函数举例

bind()是最常使用的函数,? 注意方法签名上data参数, 可以在事件处理之前传递一些附加的数据:

?

(2) 使用脚本将数据传递给事件处理函数:

方法1便于存储和查找数据. 但是自定义属性通过不W3C验证.

方法2必须要自己想办法存储数据, 并且要制定规则查找指定元素的数据.

从"开发人员"的角度方法1要更加简单直观. 但是缺点比较严重. 所以如何取舍请大家自己决定.

one( type, [data], fn ) 函数和bind一样, 但是只执行一次.

2. trigger( event, [data] ) 和 triggerHandler( event, [data] )

虽然为元素绑定了某些事件, 比如click, 但是有时希望在程序中触发这些事件,? 这两个函数可以实现此功能.

主要区别是trigger会出发浏览器默认的动作, 而triggerHandler不会出发.

通过下面的实例可以明确的区分这两个函数:

单击".triggerHandler"按钮时, 只调用一次,并且input元素没有获得焦点:

从零开始学习jQuery (5) 事件与事件对象

也就是说, trigger函数出发了浏览器默认的获取焦点的行为,让input元素获得了焦点, 所以再次调用了focus事件处理函数.

triggerHandler只调用为focus事件绑定的事件处理函数, 而不引发浏览器行为, 所以最后input元素没有获得焦点.

?六.快捷事件 Event Helpers

BUG提示:jquery-1.3.2-vsdoc2.js 这个最新的官方带智能提示的类库, 无法使用快捷事件, 比如click(), focus(). 使用其他版本的类库则没有问题.

虽然我们可以使用事件处理函数完成对象事件的几乎所有操作, 但是jQuery提供了对常用事件的封装. 比如单击事件对应的两个方法click()和click(fn)分别用来触发单击事件和设置单击事件.

设置单击事件:

有两个div(红色区域), 里面分别嵌套了一个div(黄色区域). HTML代码如下:

很多时候我们不希望出现上图的结果,? 而是希望只有鼠标在Outer1内部移动时不触发事件, Outer2使用Hover()函数实现了这个效果:

从零开始学习jQuery (5) 事件与事件对象

注意这里的事件名称进入叫做"mouseenter", 离开叫做"mouseleave", 而不再使用"mouseover"和"mouseleave"事件.

有经验的开发人员会立刻想到在制作弹出菜单时, 经常遇到这个问题: 为弹出菜单设置了mouseout事件自动关闭, 但是鼠标在弹出菜单内移动时常常莫名其妙触发mouseout事件让菜单关闭. hover()函数帮助我们很好的解决了这个问题.

2. toggle( fn, fn2, fn3,fn4,... )

toggle函数可以为对象添加click事件绑定函数,? 但是设置每次点击后依次的调用函数。

如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数,如果有更多函数,则再次触发,直到最后一个。随后的每次点击都重复对这几个函数的轮番调用。

可以使用unbind("click")来删除。

下面的示例演示如何使用toggle函数:

result上一个事件处理函数返回的值
$("p").click(function(event) {  return "hey"});$("p").click(function(event) {  alert( event.result );});

结果:"hey"timeStamp事件发生时的时间戳.
var last;$("p").click(function(event) {   if( last )      alert( "time since last event " + event.timeStamp - last );   last = event.timeStamp;});

上面是jQuery官方文档中提供的event对象的属性. 在"jQuery实战"一书中还提供了下面的多浏览器支持的属性, 时间关系我没有尝试每一个属性, 大家可以帮忙验证是否在所有浏览器下可用:

属性名称描述举例altKeyAlt键是否被按下. 按下返回true?ctrlKeyctrl键是否被按下, 按下返回true?metaKeyMeta键是否被按下, 按下返回true.
meta键就是PC机器的Ctrl键,或者Mac机器上面的Command键?shiftKeyShift键是否被按下, 按下返回true?keyCode对于keyup和keydown事件返回被按下的键. 不区分大小写, a和A都返回65.

对于keypress事件请使用which属性, 因为which属性跨浏览时依然可靠.?which对于键盘事件, 返回触发事件的键的数字编码. 对于鼠标事件, 返回鼠标按键号(1左,2中,3右).?screenX/Y对于鼠标事件, 获取事件相对于屏幕原点的水平/垂直坐标?

?

事件对象除了拥有属性, 还拥有事件. 有一些是一定会用到的事件比如取消冒泡 stopPropagation() 等.下面是jQuery事件对象的函数列表:

名称说明举例preventDefault() 取消可能引起任何语意操作的事件. 比如<a>元素的href链接加载, 表单提交以及click引起复选框的状态切换.
$("a").click(function(event){  event.preventDefault();  // do something});
isDefaultPrevented() 是否调用过preventDefault() 方法
$("a").click(function(event){  alert( event.isDefaultPrevented() );  event.preventDefault();  alert( event.isDefaultPrevented() );});
stopPropagation() 取消事件冒泡
$("p").click(function(event){  event.stopPropagation();  // do something});
isPropagationStopped() 是否调用过stopPropagation() 方法
$("p").click(function(event){  alert( event.isPropagationStopped() );  event.stopPropagation();  alert( event.isPropagationStopped() );});
stopImmediatePropagation() 取消执行其他的事件处理函数并取消事件冒泡.

如果同一个事件绑定了多个事件处理函数, 在其中一个事件处理函数中调用此方法后将不会继续调用其他的事件处理函数.
$("p").click(function(event){  event.stopImmediatePropagation();});$("p").click(function(event){  // This function won't be executed});
isImmediatePropagationStopped()