14-讨论
9.3.3 讨论
1.处理事件的所有绑定
前面已经说明, setup()
函数指在添加第一个处理程序时调用。
如果在这个事件上封装的逻辑不需要在每次执行新绑定时进行某些操作,这样就已经足够了。
jQuery提供了这种选项,但是从jQuery 1.3.3开始该方法已经有了变化。
如果使用的是旧的版本,那么需要使用 jQuery.event.specialAll
代替 jQuery.event.special
。 jQuery.event.specialAll
将接受同类对象,回调也将接受相同的参数。唯一的区别是返回false不会带来任何改变。
在jQuery 1.3.3中删除了 jQuery.event.specialAll
。为了拦截对事件的所有绑定,需要在 jQuery.event.special
命名空间中包含一个 add()
(以及可选的 remove()
)函数。这些函数的参数是将要绑定的处理程序,可以选择返回一个替代的新处理程序函数。
2.一个真实的示例
编写一个简单的示例,确保对前面的说明有清晰的理解。将使用jQuery 1.3.3+的方法。
假定我们想要在一个元素被选中(单击)且不在禁用状态的时候触发一个事件。我们将在元素具有CSS类 disabled
时断定它被禁用。
下面是具体的做法:
// 保存这些变量使代码更简短,不要在全局作用域中这么做
var event = jQuery.event;
var $selected = event.special.selected = {
setup:function( data ){
event.add(this, 'click', $selected.handler);
return false;
},
teardown:function(){
event.remove(this, 'click', $selected.handler);
return false;
},
handler:function(){
var $elem = jQuery(this);
if( !$elem.hasClass('disabled') )
$elem.triggerHandler('selected');
}
};
正如你所看到的,提供了自己的 selected
事件处理程序。在该处理程序中,使用 triggerHandler()
代替 trigger()
,因为不需要事件冒泡,也不需要阻止默认操作,所以省略了一些不必要的处理。
3.这种功能的现有用例
jQuery.event.special
是添加新的行为而又不用污染jQuery命名空间的一个极佳方法。
jQuery.event.special
并不是在任何时候都合适的,但是当需要基于另一个事件(在例子中是click)的自定义事件时,它通常很方便。如果有一个简单地绑定或者模拟事件的插件,这种方法也很有用,可以将该插件当成常规事件“掩盖”起来。
jQuery核心使用 jQuery.event.special
处理与 document.ready
事件绑定的事件。实际上,它们被当作常规的事件处理程序存储,但是在第一次绑定该事件时,实际上激活的是检测的代码。
jQuery.event.special
还用于透明地处理 mouseenter/mouseleave
事件(用于 hover()
)。实现这一功能的所有DOM遍历操作都很好地隐藏在 setup()
处理程序中。
有一些插件也利用了 jQuery.event.special
。下面列出这类的插件中的几个:
mousewheel
提供对鼠标滚轮变化的支持。[2]
drag
、 drop
将拖放支持伪装成简单的事件。[3]
focusin, focusout
这个代码段(不是真正的插件)原来是Jörn Zaefferer编写的,后来通过插件添加,实现 focus
和 blur
事件的事件委托。
如果你计划为jQuery添加新的事件,查看这些插件是个好的开始。