目录
一、绑定事件
使用jQuery事件模型,可以利用bind() 方法在DOM元素上创建事件处理器。bind函数使用如下所示:
方法语法:bind
bind(eventType, data, hanlder)
bind(eventMap)
创建一个函数,将其作为在匹配集中所有元素上指定的事件类型的事件处理器
参数
eventType (字符串)为将要创建的处理器指定事件类型的名称。可以使用空格分隔的列表指定多个事件类型
通过在事件名称的后面添加圆点字符分隔的后缀,这些事件类型可以指定命名空间。本节的剩余部分会对其进行详细介绍
data (对象)调用者提供的数据,用来附加到Event 实例的data 属性,以便为处理器函数所使用。如果省略,可以指定第二个参数为处理器函数
handler (函数)将要创建为事件处理器的函数。当调用此函数时,会传入Event 实例,并设置函数上下文(this )为冒泡阶段的当前元素
eventMap (对象)一个JavaScript对象,允许在一次调用中创建多个事件类型的处理器。属性的名称指定事件类型(与eventType 参数相同),属性的值提供处理器
返回值
包装集
- 举例说明
/*
为页面上的每个图片绑定提供内联函数,作为单击事件处理器
*/
$('img').bind('click',function(event){alert('Hi there!');});
/*
对img图片添加3个事件
*/
$('img').bind({
click: function(event) { /* handle clicks */ },
mouseenter: function(event) { /* handle mouseenters */ },
mouseleave: function(event) { /* handle mouseleaves */ }
});
为了使开发者更加方便的绑定事件,JQuery封装了常用的事件以便节约更多的代码。我们称它为简写事件,见如下表格。
方法名 | 触发条件 | 描述 |
---|---|---|
click(fn) | 鼠标 | 触发每一个匹配元素的click(单击)事件 |
dblclick(fn) | 鼠标 | 触发每一个匹配元素的dblclick(双击)事件 |
mousedown(fn) | 鼠标 | 触发每一个匹配元素的mousedown(点击后)事件 |
mouseup(fn) | 鼠标 | 触发每一个匹配元素的mouseup(点击弹起)事件 |
mouseover(fn) | 鼠标 | 触发每一个匹配元素的mouseover(鼠标移入)事件 |
mouseout(fn) | 鼠标 | 触发每一个匹配元素的mouseout(鼠标移出)事件 |
mousemove(fn) | 鼠标 | 触发每一个匹配元素的mousemove(鼠标移动)事件 |
mouseenter(fn) | 鼠标 | 触发每一个匹配元素的mouseenter(鼠标穿过)事件 |
mouseleave(fn) | 鼠标 | 触发每一个匹配元素的mouseleave(鼠标穿出)事件 |
keydown(fn) | 键盘 | 触发每一个匹配元素的keydown(键盘按下)事件 |
keyup(fn) | 键盘 | 触发每一个匹配元素的keyup(键盘按下弹起)事件 |
keypress(fn) | 键盘 | 触发每一个匹配元素的keypress(键盘按下)事件 |
unload(fn) | 文档 | 当卸载本页面时绑定一个要执行的函数 |
resize(fn) | 文档 | 触发每一个匹配元素的resize(文档改变大小)事件 |
scroll(fn) | 文档 | 触发每一个匹配元素的scroll(滚动条拖动)事件 |
focus(fn) | 表单 | 触发每一个匹配元素的focus(焦点激活)事件 |
blur(fn) | 表单 | 触发每一个匹配元素的blur(焦点丢失)事件 |
focusin(fn) | 表单 | 触发每一个匹配元素的focusin(焦点激活)事件 |
focusout(fn) | 表单 | 触发每一个匹配元素的focusout(焦点丢失)事件 |
select(fn) | 表单 | 触发每一个匹配元素的select(文本选定)事件 |
change(fn) | 表单 | 触发每一个匹配元素的change(值改变)事件 |
submit(fn) | 表单 | 触发每一个匹配元素的submit(表单提交)事件 |
- 举例说明
这里封装的大部分方法都比较好理解,我们没必要一一演示确认,重点看几个需要注意区分的简写方法。
.mouseover()和.mouseout()表示鼠标移入和移出的时候触发。那么JQuery还封装了另外一组:.mouseenter()和.mouseleave()表示鼠标穿过与穿出的时候触发。那么这两组本质上有什么区别呢?手册上的说明是:.mouseenter()和.mouseleave()这组穿过子元素不会触发,而.mouseover()和.mouseout()则会触发。
<!--HTML页面设置-->
<div style="width:200px;height:200px;background:green;">
<p style="width:100px;height:100px;background:red;">
</div>
<strong></strong>
<script>
//mouseover移入
$('div').mouseover(function () {//移入div 会触发,移入p 再触发
$('strong').html(function (index, value) {
return value+'1';
});
});
//mouseenter穿过
$('div').mouseenter(function () {//穿过div 或者p
$('strong').html(function (index, value) {//在这个区域只触发一次
return value+'1';
});
});
//mouseout移出
$('div').mouseout(function () { //移出p 会触发,移出div 再触发
$('strong').html(function (index, value) {
return value+'1';
});
});
//mouseleave穿出
$('div').mouseleave(function () {//移出整个div 区域触发一次
$('strong').html(function (index, value) {
return value+'1';
});
});
.keydown()、.keyup()返回的是键码,而.keypress()返回的是字符编码。
$('input').keydown(function (e) {
alert(e.keyCode);//按下a 返回65
});
$('input').keypress(function (e) {
alert(e.charCode);//按下a 返回97
});
</script>
注意:e.keyCode和e.charCode在两种事件互换也会产生不同的效果,除了字符还有一些非字符键的区别。
.focus()和.blur()分别表示光标激活和丢失,事件触发时机是当前元素。而.focusin()和.focusout()也表示光标激活和丢失,但事件触发时机可以是子元素。
<!--HTML部分-->
<div style="width:200px;height:200px;background:red;">
<input type="text" value="" />
</div>
<strong></strong>
<script>
//focus光标激活
$('input').focus(function () {//当前元素触发
$('strong').html('123');
});
//focusin光标激活
$('div').focusin(function () {//绑定的是div 元素,子类input 触发
$('strong').html('123');
});
</script>
注意:.blur()和.focusout()表示光标丢失,和激活类似,一个必须当前元素触发,另一个可以是子元素触发。
JQuery提供了许多最常用的事件效果,组合一些功能实现了一些复合事件,比如切换功能、智能加载等。
方法名 | 描述 |
---|---|
ready(fn) | 当DOM加载完毕触发事件 |
hover([fn1,]fn2) | 当鼠标移入触发第一个fn1,移出触发fn2 |
toggle(fn1,fn2[,fn3..]) | 已废弃,当鼠标点击触发fn1,再点击触发fn2... |
- 举例说明
//背景移入移出切换效果
$('div').hover(function () {
$(this).css('background', 'black');//mouseenter 效果
}, function () {
$(this).css('background', 'red');//mouseleave 效果,可省略
});
注意:.hover()方法是结合了.mouseenter()方法和.mouseleva()方法,并非.mouseover()和.mouseout()方法。
.toggle()这个方法比较特殊,这个方法有两层含义:第一层含义就是已经被1.8版废用、1.9版删除的用法,也就是点击切换复合事件的用法;第二层含我将会在动画那章讲解到。既然废弃掉了,就不应该使用。被删除的原因是:以减少混乱和提高潜在的模块化程度。但你又非常想用这个方法,并且不想自己编写类似的功能,可以下载jquery-migrate.js文件,来向下兼容已被删除掉的方法。
//背景点击切换效果(1.9 版删除了)
<script type="text/javascript" src="jquery-migrate-1.2.1.js"></script>
$('div').toggle(function () {//第一次点击切换
$(this).css('background', 'black');
}, function () {//第二次点击切换
$(this).css('background', 'blue');
}, function () {//第三次点击切换
$(this).css('background', 'red');
});
/*
注意:由于官方已经删除掉这个方法,所以也是不推荐使用的,
如果在不基于向下兼容的插件JS。我们可以自己实现这个功能。
*/
var flag = 1;//计数器
$('div').click(function () {
if (flag == 1) {//第一次点击
$(this).css('background', 'black');
flag = 2;
} else if (flag == 2) {//第二次点击
$(this).css('background', 'blue');
flag = 3
} else if (flag == 3) {//第三次点击
$(this).css('background', 'red');
flag = 1
}
});
二、解绑事件
jQuery为事件处理提供了额外功能,就是通过指定命名空间来对事件处理器进行分组。和常规的命名空间不同(通过前缀指定命名空间),它通过为事件名称添加以圆点分隔的后缀来指定命名空间。事实上,如果你愿意,可以使用多个后缀将事件归入多个命名空间。
通过这种方式对事件绑定进行分组,随后就可以将它们看作一个单元以便对其进行操作。
例如,一个页面有两种模式:显示模式和编辑模式。在编辑模式下,事件监听器放置在页面的许多元素上,但是在显示模式下这些监听器都不适用了,因此当页面离开编辑模式时,就需要删除这些监听器。我们可以为编辑模式下的事件指定命名空间,代码如下所示:
$('#thing1').bind('click.editMode',someListener);
$('#thing2').bind('click.editMode',someOtherListener);
//当页面离开编辑模式需要删除所有的绑定时
$('*').unbind('click.editMode');
方法语法:unbind
unbind(eventType, listener)
unbind(event)
为包装集中的所有元素删除由可选的传入参数指定的事件处理器。如果没有提供参数,则会从元素上删除所有的监听器
参数
eventType (字符串)如果提供,则只删除为指定事件类型创建的监听器
listener (函数)如果提供,则找出将要删除的指定监听器
Event (事件)删除触发Event 实例描述的事件的监听器
返回值
包装集
三、事件对象
事件对象就是event对象,通过处理函数默认传递接受。之前处理函数的e就是event事件对象,event对象有很多可用的属性和方法,如下实例:
//通过处理函数传递事件对象
$('input').bind('click', function (e) { //接受事件对象参数
alert(e);
});
属性名 | 描述 |
---|---|
type | 获取这个事件的事件类型,如click |
target | 获取绑定事件的DOM元素 |
data | 获取事件调用时的额外数据 |
relatedTarget | 获取移入移出目标点离开或进入的那个DOM元素 |
currentTarget | 获取冒泡前触发的DOM元素,等同于this |
pageX,pageY | 获取相对于页面原点的水平/垂直坐标 |
screenX,screenY | 获取显示器屏幕位置的水平/垂直坐标(非JQuery封装) |
clientX,clientY | 获取相对于页面视口的水平/垂直坐标(非JQuery封装) |
result | 从前面的事件处理器返回的最近的非undefined 的值 |
timeStamp | 获取事件触发的时间戳 |
which | 对于键盘事件,指定触发事件的按键的数字代码;对于鼠标事件,指定按下的是哪个按钮(1 为左键、2 为中键、3 为右键)。应该使用which 属性代替button 属性,因为不能保证跨浏览器button 属性的一致性 |
altKey | 当触发事件时,如果Alt键已被按下,则设置为true ,否则为false 。在大部分的Mac键盘中Alt键标记为Option |
ctrlKey | 当触发事件时,如果Ctrl键已被按下,则设置为true ,否则为false |
metaKey | 当触发事件时,如果Meta键已被按下,则设置为true ,否则为false 。在PC上Meta键是Ctrl键,而在Mac上是Command键 |
shiftKey | 当触发事件时,如果Shift键已被按下,则设置为true ,否则为false |
- 举例说明
//通过event.type 属性获取触发事件名
$('input').click(function (e) {
alert(e.type);
});
//通过event.target 获取绑定的DOM 元素
$('input').click(function (e) {
alert(e.target);
});
//通过event.data 获取额外数据,可以是数字、字符串、数组、对象
$('input').bind('click', 123, function () {//传递data 数据
alert(e.data);//获取数字数据
);
注意:如果字符串就传递:'123',如果是数组就传递:[123,'abc'],如果是对象就传递:
{user: 'Lee', age: 100}。数组的调用方式是:e.data[1],对象的调用方式是:e.data.user。
//event.data获取额外数据,对于封装的简写事件也可以使用
$('input').click({user: 'Lee', age: 100},function (e) {
alert(e.data.user);
});
注意:键值对的键可以加上引号,也可以不加;在调用的时候也可以使用数组的方式:
alert(e.data['user']);
//获取移入到div 之前的那个DOM 元素
$('div').mouseover(function (e) {
alert(e.relatedTarget);
});
//获取移出div 之后到达最近的那个DOM 元素
$('div').mouseout(function (e) {
alert(e.relatedTarget);
});
//获取绑定的那个DOM 元素,相当于this,区别于event.target
$('div').click(function (e) {
alert(e.currentTarget);
});
注意:event.target得到的是触发元素的DOM,event.currentTarget得到的是监听元素的DOM。而this也是得到监听元素的DOM。
//获取上一次事件的返回值
$('div').click(function (e) {
return '123';
});
$('div').click(function (e) {
alert(e.result);
});
//获取当前的时间戳
$('div').click(function (e) {
alert(e.timeStamp);
});
//获取鼠标的左中右键
$('div').mousedown(function (e) {
alert(e.which);
});
//获取键盘的按键
$('input').keyup(function (e) {
alert(e.which);
});
//获取是否按下了ctrl 键,meta 键不存在,导致无法使用
$('input').click(function (e) {
alert(e.ctrlKey);
});
//获取触发元素鼠标当前的位置
$(document).click(function (e) {
alert(e.screenY+ ',' + e.pageY + ',' + e.clientY);
});
方法 | 描述 |
---|---|
preventDefault() | 阻止任意默认的语义动作(比如表单提交、链接重定向、复选框状态的改变等)发生 |
stopPropagation() | 停止事件沿着DOM树向上进一步传播。当前目标元素上附加的事件不受影响。不仅支持浏览器定义的事件,而且支持自定义事件 |
stopImmediatePropagation() | 停止所有事件的进一步传播,包括附加在当前目标元素上的事件 |
isDefaultPrevented() | 如果已经在此实例上调用了preventDefault() 方法,则返回true |
isPropagationStopped() | 如果已经在此实例上调用了stopPropagation() 方法,则返回true |
isImmediatePropagationStopped() | 如果已经在此实例上调用了stopImmediatePropagation() 方法,则返回true |
四、高级事件
在事件触发的时候,有时我们需要一些模拟用户行为的操作。例如,当网页加载完毕后自行点击一个按钮触发一个事件,而不是由用户去点击。
//点击按钮事件
$('input').click(function () {
alert('我的第一次点击来自模拟!');
});
//模拟用户点击行为
$('input').trigger('click');
//可以合并两个方法
$('input').click(function () {
alert('我的第一次点击来自模拟!');
}).trigger('click');
有时在模拟用户行为的时候,我们需要给事件执行传递参数,这个参数类似于event.data的额外数据,可以是数字、字符串、数组、对象。
$('input').click(function (e, data1, data2) {
alert(data1 + ',' + data2);
}).trigger('click', ['abc', '123']);
注意:当传递一个值的时候,直接传递即可。当两个值以上时,需要在前后用中括号包含起来。但不能认为是数组形式,下面给出一个复杂的说明。
$('input').click(function (e, data1, data2) {
alert(data1.a + ',' + data2[1]);
}).trigger('click', [{'a': '1', 'b': '2'}, ['123','456']]);
除了通过JavaScript事件名触发,也可以通过自定义的事件触发。所谓自定义事件,其实就是一个被.bind()绑定的任意函数。
$('input').bind('myEvent', function () {
alert('自定义事件!');
}).trigger('myEvent');
.trigger()方法提供了简写方案,只要想让某个事件执行模拟用户行为,直接再调用一个空的同名事件即可。
$('input').click(function () {
alert('我的第一次点击来自模拟!');
}).click();//空的click()执行的是trigger()
这种便捷的方法,JQuery几乎所有常用的事件都提供了。
blur | focusin | mousedown | resize |
change | focusout | mousenter | scroll |
click | keydown | mouseleave | select |
dblclick | keypress | mousemove | submit |
error | keyup | mouseout | unload |
focus | load | mouseover |
JQuery还提供了另外一个模拟用户行为的方法:.triggerHandler();这个方法的使用和.trigger()方法一样。
$('input').click(function () {
alert('我的第一次点击来自模拟!');
}).triggerHandler('click');
在常规的使用情况下,两者几乎没有区别,都是模拟用户行为,也可以传递额外参数。但在某些特殊情况下,就产生了差异:
(1)triggerHandler()方法并不会触发事件的默认行为,而.trigger()会。
$('form').trigger('submit');//模拟用户执行提交,并跳转到执行页面
$('form').triggerHandler('submit');//模拟用户执行提交,并阻止的默认行为
// 如果我们希望使用.trigger()来模拟用户提交,并且阻止事件的默认行为,则需要这么写:
$('form').submit(function (e) {
e.preventDefault();//阻止默认行为
}).trigger('submit');
(2)triggerHandler()方法只会影响第一个匹配到的元素,而.trigger()会影响所有。
(3)triggerHandler()方法会返回当前事件执行的返回值,如果没有返回值,则返回undefined;而.trigger()则返回当前包含事件触发元素的JQuery对象(方便链式连缀调用)。
alert($('input').click(function () {
return 123;
}).triggerHandler('click'));//返回123,没有return 返回
(4)trigger()在创建事件的时候,会冒泡。但这种冒泡是自定义事件才能体现出来,是JQuery扩展于DOM的机制,并非DOM特性。而.triggerHandler()不会冒泡。
jQuery提供了我们所期望的live() 方法,该方法允许预先为那些还不存在的元素创建事件处理器。live() 的语法如下。
方法语法:live
live(eventType, data, listener)
当指定类型的事件在元素(任何用来创建包装集的与选择器相匹配的元素)上发生时,会将传入的监听器作为处理器调用,而无论在调用live 方法时这些元素是否已经存在
参数
eventType (字符串)指定处理器将要调用的事件类型的名称。和bind() 不同,不能指定空格分隔的事件类型列表3
3 这个说法不对,从jQuery1.4开始已经可以为live() 方法的第一个参数指定空格分隔的事件类型列表或者自定义事件类型了。
data (对象)调用者提供的数据,用来附加到Event 实例的data 属性,以便为处理器函数所使用。如果省略,可以指定第二个参数为处理器函数
listener (函数)将要作为事件处理器被调用的函数。当调用此函数时,会向此函数传入Event实例,并设置目标元素为函数上下文(this )
返回值
包装集
如果这个方法的语法让你想起bind() 方法的语法,那就对了。这个方法的定义和行为与bind() 很相似。不同之处是,当相应的事件发生时,该方法会为所有匹配选择器的元素触发此事件,甚至包括那些在调用live() 的时候还不存在的元素。
$('div.attendToMe').live(
'click',
function(event){ alert(this); }
);
在页面的整个生命周期内,单击任意拥有类attendToMe 的<div> 元素都会调用事件处理器并传入一个事件实例。而且前面的代码不需要放置于就绪处理器中,因为“live”事件不关心DOM是否已经存在。
利用live() 方法,可以非常容易地在页面上的某个地方创建需要的事件处理器,而无需担心元素是否已经存在,或者什么时候创建元素。
但是使用live() 时必须要遵守一些注意事项。因为它和bind() 很相似,你可能会期望“live”事件完全按照与原生事件相同的方式工作,但是它们是有差异的,在某些页面中这种差异可能很重要,也可能无关紧要。
首先,要意识到“live”事件不是 原生的“普通”事件。当类似于单击的事件发生时,它会沿着DOM元素向上传播(如前所述),并调用每一个已经创建的事件处理器。一旦事件到达用来创建包装集的上下文,也就是调用live() 的地方(通常是文档根节点4 ),上下文会在子节点中检查匹配“live”选择器的元素5 。“live”事件处理器会在每个匹配的元素上触发,并且这个已触发的事件不能 继续传播。
方法语法:die
die(eventType, listener)
删除由live() 创建的“live”事件处理器,并且阻止在将来创建的元素上调用处理器,这些元素是与调用live() 时使用的选择器相匹配的元素
参数
eventType (字符串)如果提供,则只删除为指定事件类型创建的监听器
listener (函数)如果提供,则找出将要删除的指定监听器
返回值
包装集