jQuery事件处理
一、就绪处理器事件的绑定方法
1、bind(eventType, data, hanlder)
创建一个函数,将其作为在匹配集中的所有元素上指定的时间类型的事件处理器
参数:
eventType: (字符串)为将要创建的处理器指定事件类型的名称。可以使用空格分隔的列表指定多个事件类型 。
data:(对象)调用者提供的数据,用来附加到event实例的data属性,以便处理器函数所使用。如果省略,则第二个参数为处理器函数
handler: (函数)将要创建为事件处理器的函数。当调用此函数时,会传入Event实例
2、one(eventType, data, listener)
创建一个函数,并将其作为匹配集中所有元素指定事件类型的事件处理器。这个处理器一旦执行完毕,就会被自动删除
参数:
eventType: (字符串)为将要创建的处理器指定事件类型的名称。
data: 调用者提供的数据,用来附加到event实例中以便为处理器函数所使用。如果省略,则可以指定第二参数为处理器函数
listener: (函数)将要被创建为一次性事件处理器的函数
3、unbind(eventType, listener)
二、预先管理事件处理器
使用bind()和unbind()方法,可以很容易地控制要在DOM中的元素上创建哪些事件处理器。就绪处理器的方便在于可以从头开始在DOM元素上创建处理器。这些DOM元素或者通过页面上的HTML标记创建,或者是在就绪处理器上创建。
但是在页面中我们很经常频繁地引入DOM元素获删除它们,在管理这些动态元素的事件处理器时,就绪处理器就起不到多大作用了。因为这个动态元素在就绪处理器执行时还不存在。
1、创建“live”事件处理
live()允许预先为那些还不存在的元素创建时间处理器
live(eventType, data, listener)
指定类型的时间元素上发生时,会将传入的监听器作为处理器调用,而无论在调用live方法时这些元素是否已经存在
注意:livelive方法把监听器绑定到了document上了。不把监听器直接绑定在元素上,所以方法内部的this不代表元素。
缺点:只能应用于选择器,不能应用于衍生而来的包装集
$(‘img‘).live(...); (正确)
$(‘img‘).closest(‘div‘).live(...) (错误)
2、删除‘live‘事件处理器
die(eventType,listener)
三、其它事件的相关方法
1、起切换作用的监听器
toggle(listener1, listener2, ...)
将传入的函数创建为包装集中所有元素的单击事件处理器的循环列表。处理器将以此在随后的单击事件中被调用
2、hover绑定方法
hover(enterHanlder, leaveHandler)
为匹配元素创建mouseenter和mouseleave事件处理器,这些处理器只会在鼠标进入或者离开元素覆盖的区域时触发,而忽略移动到子元素的转变
参数:
enterHandler (函数)将成为mouseenter处理器的函数
leaveHandler (函数)将要成为mouseleave处理器的函数
返回值:包装集
四、Event对象
1、Event属性
属性 |
描述 |
altKey |
当alt键已经按下,则设置为ture,否则为false |
ctrlKey |
当Ctrl键已经按下,则设置为ture,否则为false |
currentTarget |
冒泡阶段的当前元素。它和事件处理器函数上下文对象是同一个对象 |
data |
如果有值得话,在创建处理器时,将其作为第二个参数传入bind() |
metaKey |
当触发时间时,当Ctrl键(苹果对应的是comand)键已经按下,则返回true |
pageX |
对于鼠标事件,指定触发事件时光标相对于页面圆点的水平坐标 |
pageY |
对于鼠标事件,指定触发事件时光标相对于页面圆点的垂直坐标 |
relatedTarget |
对于鼠标事件,找出触发事件时光标离开或者进入的元素 |
screenX |
对于鼠标事件,指定触发事件时光标相对于屏幕原点的水平坐标 |
screenY |
对于鼠标事件,指定触发事件时光标相对于屏幕原点的垂直坐标 |
shiftkey |
当触发事件时,如果shift键已经被按下,则设置为true,否则为false |
target |
找出触发事件的元素 |
timestramp |
jQuery.Event实例创建时的事件戳,以毫秒为单位 |
type |
为所有的事件指定触发的事件类型(例如click)。如果使用一个时间处理器来处理多个事件,那么这个非常有用 |
which |
对于键盘事件,指定触发事件的数字代码;对于鼠标事件,则指定按下的是哪个按钮(1为左键,2为中键,3为右键) |
2、方法
属性 |
描述 |
preeventDefault() |
阻止任意默认的寓意动作(比如表单提交、链接重定向、复选框状态的改变)等 |
stopProgation() |
停止事假沿着DOM树上进一步传播。当前目标元素上附加的事件不受影响,而且支持自定义事件 |
stopImmediatePropagation() |
停止所有事件沿着DOM树向上进一步传播。包括当前附加元素上的事件 |
isDefaultPropagation() |
如果已经在此实例上调用了preventDefault()方法,则返回true |
isPropagationStopped() |
如果已经调用了stopProgation()方法,则返回true |
isImmediatePropagationStopped() |
对于鼠标事件,指定触发事件时光标相对于页面圆点的水平坐标 |
五、总结
绑定 |
bind |
live |
delegate |
on |
解绑 |
unbind |
die |
undelegate |
off |
此外,还有一种事件绑定方式a.click(function(){});a.change(function(){});,它们的作用于bind一样,仅仅只是简写而已。
bind的特点就是会把监听器绑定到目标元素上,有一个绑一个,在页面上的元素不会动态添加的时候使用它没什么问题。但如果列表中动态增加一个元素,点击它是没有反应的,必须再bind一次才行。
要想不这么麻烦,我们可以使用live。live方法把监听器绑定到了document上了。不把监听器直接绑定在元素上live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document。在监听函数中,我们可以用event.currentTarget来获取到当前捕捉到事件的节点。
例子:
$(‘#myol li‘).live(‘click‘,getHtml);使用事件委托的优点一目了然,新添加的元素不必再绑定一次监听器。看来live这货还真不错,以后抛弃bind就用它了!可以吗?答案是否定的,而且是大大的否定。因为将监听器绑定到了document上,所以事件的处理得等待层层冒泡,直到冒泡到根节点才开始处理。为此,jQuery官方已宣布在1.7版本开始废弃live,改用其他方式代替。正因为live存在那样的缺点,所以考虑绑定在就近的父级元素上不就好了。
顺应正常逻辑,delegate诞生了。delegate(selector,type,[data],fn)参数多了一个selector,用来指定触发事件的目标元素,监听器将被绑定在调用此方法的元素上。最后是on方法,on(type,[selector],[data],fn)参数与delegate差不多但还是有细微的差别,首先type与selector换位置了,其次selector变为了可选项。交换位置的原因不好查证,应该是为了让视觉上更舒服一些吧。例子:$(‘#myolli‘).on(‘click‘,getHtml);可以看到event.currentTarget是li自己,与bind的效果一样。至于传selector进去,就是跟delegate一样的意义了,除了参数顺序不同,其他完全一样。
官方有一个推荐就是尽量使用on,因为其他方法都是内部调用on来完成的,直接使用on可以提高效率,而且你完全可以用on来代替其他三种写法。至于如何代替我想就不必这么直白的写出来了,真正理解它们的区别之后自然而然也就不是难事了。