jQuery基础事件
JavaScript有一个非常重要的功能,就是事件驱动。当页面完全加载后,用户通过鼠标或键盘触发页面中绑定事件的元素即可触发。jQuery为开发者更有效率的编写事件行为,封装了大量有益的事件方法供我们使用。
一.绑定事件
在JavaScript中,常用的事件有:click、dblclick、mousedown、mouseup、mousemove、mouseover、mouseout、change、select、submit、keydown、keypress、keyup、blur、focus、load、resize、scroll、error。
jQuery通过.bind()方法来为元素绑定这些事件。可以传递三个参数:bind(type,[data],fn),type表示一个或多个类型的事件名字符串;[data]是可选的,作为event.data属性值传递一个额外的数据,这个数据是一个字符串、一个数字、一个数组或一个对象;fn表示绑定到指定元素的处理函数。
<body> <form> <input type="button" value="按钮" /> </form> </body>
使用点击事件通过.bind封装
第一种方式:匿名函数
$(function () { $('input').bind('click', function () { //点击按钮后执行匿名函数 alert('弹窗!'); }); });
第二种方式:普通处理函数
$(function () { $('input').bind('click',fn); //执行普通函数式无须圆括号 function fn() { alert('处理函数!') } });
第三种方式:可以同时绑定多个事件
(1)鼠标移到执行事件1弹出当点击执行事件2
$(function () { $('input').bind('click mouseover', function () { alert('弹窗!'); }); });
~~~
<body> <input type="button" value="按钮" /> <div></div> </body>
(2)当鼠标移入到按钮上显示1,离开按钮又显示一个1
$(function () { $('input').bind('mouseover mouseout',function () { //移入和移出分别执行一次 $('div').html(function (index,value) { return value + '1'; }); }); });
通过对象键值对绑定多个参数
当鼠标移入到按钮上显示移,离开按钮又显示移出
$(function () { $('input').bind({ //传递一个对象 mouseover : function () { //事件名的引号可以省略 alert('移入'); }, mouseout : function () { alert('移出'); } }); });
使用unbind删除绑定的事件
$(function () { $('input').bind('click mouseover', function () { alert('弹窗!'); }); $('input').unbind(); //删除全部事件 });
使用unbind参数删除指定类型事件
当鼠标移入到按钮上mouseover事件弹出保留,点击按钮click事件删除
$(function () { $('input').bind('click mouseover', function () { alert('弹窗!'); }); $('input').unbind('click'); //只删除click事件 });
使用unbind参数删除指定处理函数的事件
俩个事件fn1和fn2只删除fn2的事件
$(function () { $('input').bind('click',fn1); $('input').bind('click',fn2); function fn1() { alert('fn1'); } function fn2() { alert('fn2'); } $('input').unbind('click',fn2); //删除click事件绑定了fn2的 });
二.简写事件
为了使开发者更加方便的绑定事件,jQuery封装了常用的事件以便节约更多的代码。我们称它为简写事件。
1.简写事件绑定方法
鼠标触发
(1)click(fn)鼠标触发每一个匹配元素的click(单击)事件
$(function () { $('input').click(function () { alert('单击'); }); });
(2)dblclick(fn)鼠标 触发每一个匹配元素的dblclick(双击)事件
$(function () { $('input').dblclick(function () { alert('双击'); }); });
(3)mousedown(fn)鼠标触发每一个匹配元素的mousedown(点击后)事件
$(function () { $('input').mousedown(function () { alert('鼠标左键按下'); }); });
(4)mouseup(fn)鼠标触发每一个匹配元素的mouseup(点击弹起)事件
$(function () { $('input').mouseup(function () { alert('鼠标左键按下弹起'); }); });
.mouseover()和.mouseout()表示鼠标移入和移出的时候触发。那么jQuery还封装了另外一组:.mouseenter()和.mouseleave()表示鼠标穿过和穿出的时候触发。.mouseenter()和.mouseleave()这组穿过子元素不会触发,而.mouseover()和.mouseout()则会触发。
(5-6html代码)
<body> <div style="width:200px;height:200px;background:green;"> </div> </body>
(5)mouseover(fn)鼠标触发每一个匹配元素的mouseover(鼠标移入)事件
(6)mouseout(fn)鼠标触发每一个匹配元素的mouseout(鼠标移出)事件
当鼠标移入里变为红色,当鼠标移出时返回成绿色
$(function () { $('div').mouseover(function () { $(this).css('background', 'red'); }).mouseout(function () { $(this).css('background', 'green'); }); });
(7-9html代码)
<body> <div style="width:200px;height:200px;background:green;"> <p style="width:100px;height:100px;;background:red;"></p> </div> <strong></strong> </body>
(7)mousemove(fn)鼠标 触发每一个匹配元素的mousemove(鼠标移动)事件
当鼠标移入里变为红色,当鼠标移出时返回成绿色
over会触发子节点
$(function () { $('div').mouseenter(function () { $(this).css('background', 'red'); }).mouseleave(function () { $(this).css('background', 'green'); }); $('div').mouseover(function() { //over会触发子节点 $('strong').html(function (index, value) { return value + '1'; }); }); });
(8)mouseenter(fn)鼠标 触发每一个匹配元素的mouseenter(鼠标穿过)事件
$(function () { $('div').mouseenter(function () { $(this).css('background', 'red'); }).mouseleave(function () { $(this).css('background', 'green'); }); $('div').mouseenter(function() { //enter不会触发子节点 $('strong').html(function (index, value) { return value + '1'; }); }); });
(9)mouseleave(fn)鼠标 触发每一个匹配元素的mouseleave(鼠标穿出)事件
mouseleave在里面不会触发任何节点,完全离开div区域产生触发
$(function () { $('div').mouseenter(function () { $(this).css('background', 'red'); }).mouseleave(function () { $(this).css('background', 'green'); }); $('div').mouseleave(function() { $('strong').html(function (index, value) { return value + '1'; }); }); });
键盘:
<body> <input type="text" value="" /> </body>
(1)keydown(fn)键盘触发每一个匹配元素的keydown(键盘按下)事件
当键盘按下任何键位弹出对话框
$(function () { $('input').keydown(function () { alert('键盘'); }); });
(2)keyup(fn)键盘触发每一个匹配元素的keyup(键盘按下弹起)事件
当键盘按下任何键位松开时弹出对话框
$(function () { $('input').keyup(function () { alert('键盘'); }); });
(3)keypress(fn)键盘 触发每一个匹配元素的keypress(键盘按下)事件
当键盘按下任何键位弹出对话框返回的对应的值字符编码
$(function () { $('input').keydown(function (e) { alert(e.keyCode); }); });
注意:e.keyCode和e.charCode在两种事件互换也会产生不同的效果,除了字符还有一些非字符键的区别。更多详情可以了解JavaScript事件处理那章。
文档:
(1)unload(fn)文档当卸载本页面时绑定一个要执行的函数
$(function () { $(window).unload(function () { //一般unload卸载页面新版浏览器应该是不支持的,获取要设置一个。 alert('1'); //刷新弹出1。一般用于清理工作。 }); });
(2)resize(fn)文档触发每一个匹配元素的resize(文档改变大小)事件
窗口大小改变弹出
$(function () { $(window).resize(function () { alert('文档改变了'); }); });
(3)scroll(fn)文档触发每一个匹配元素的scroll(滚动条拖动)事件
滚动条拖动弹出
$(function () { $(window).scroll(function () { alert('滚动条改变了'); }); });
.focus()和.blur()分别表示光标激活和丢失,事件触发时机是当前元素。而.focusin()和.focusout()也表示光标激活和丢失,但事件触发时机可以是子元素。
<body> <body> <input type="text" value="" /> </body>
(4)focus(fn)表单触发每一个匹配元素的focus(焦点激活)事件
<body> <div style="width:200px;height:200px;background:green;"> <input type="text" value="" /> </div> </body>
当光标点击文档里弹出
$(function () { $('input').focus(function () { //focus必须是当前元素才能激活 alert('光标激活'); }); });
(5)blur(fn)表单触发每一个匹配元素的blur(焦点丢失)事件
$(function () { $('input').blur(function () { //blur必须是当前元素才能激活 alert('光标丢失'); }); });
(6)focusin(fn)表单触发每一个匹配元素的focusin(焦点激活)事件
$(function () { $('div').focusin(function () { //focusin可以是子元素激活 alert('光标丢失'); }); });
(7)focusout(fn)表单触发每一个匹配元素的focusout(焦点丢失)事件
$(function () { $('div').focusout(function () { //focusout可以是子元素激活 alert('光标丢失'); }); });
注意:.blur()和.focusout()表示光标丢失,和激活类似,一个必须当前元素触发,一个可以是子元素触发。
(8)select(fn)表单触发每一个匹配元素的select(文本选定)事件
<body> <input type="test" value="文本" /> </body>
选定文本的时候触发事件弹出
$(function () { $('input').select(function () { alert('文本选定'); }); });
change(fn)表单触发每一个匹配元素的change(值改变)事件
文本内容改变的时候触发事件弹出
$(function () { $('input').change(function () { alert('文本改变'); }); });
submit(fn)表单触发每一个匹配元素的submit(表单提交)事件
<body> <form> <input type="submit" value="文本" /> </form> </body>
当点击提交文本时触发
$(function () { $('form').submit(function () { alert('表单提交!'); }); });
三.复合事件
jQuery提供了许多最常用的事件效果,组合一些功能实现了一些复合事件,比如切换功能、智能加载等。
(1)ready(fn)当DOM加载完毕触发事件
(2)hover([fn1,]fn2)当鼠标移入触发第一个fn1,移出触发fn2
当鼠标移入变为红色移除变为绿色
$(function () { $('div').hover(function () { $(this).css('background', 'red'); }, function () { $(this).css('background', 'green'); }); });
注意:.hover()方法是结合了.mouseenter()方法和.mouseleva()方法,并非.mouseover()和.mouseout()方法。
(3)toggle(fn1,fn2[,fn3..]) 已废弃,当鼠标点击触发 fn1,再点击触发 fn2...
.toggle()这个方法比较特殊,这个方法有两层含义,第一层含义就是已经被 1.8 版废用、1.9 版删除掉的用法,也就是点击切换复合事件的用法。第二层函数将会在动画那章讲解到。既然废弃掉了,就不应该使用。被删除的原因是:以减少混乱和提高潜在的模块化程度。
但你又非常想用这个方法,并且不想自己编写类似的功能,可以下载jquery-migrate.js文件,来向下兼容已被删除掉的方法。
注意:由于官方已经删除掉这个方法,所以也是不推荐使用的,如果在不基于向下兼容的插件JS。我们可以自己实现这个功能。
当点击鼠标分别变换成红色,蓝色,绿色
$(function () { var flag = 1; $('div').click(function () { if (flag == 1) { $(this).css('background', 'red'); flag = 2; } else if (flag == 2) { $(this).css('background', 'blue'); flag = 3; } else if (flag == 3) { $(this).css('background', 'green'); flag = 1; } }); });
jQuery事件对象
JavaScript 在事件处理函数中默认传递了event对象,也就是事件对象。但由于浏览器的兼容性,开发者总是会做兼容方面的处理。jQuery在封装的时候,解决了这些问题,并且还创建了一些非常好用的属性和方法。
一.事件对象
事件对象就是event对象,通过处理函数默认传递接受。之前处理函数的e就是event事件对象,event对象有很多可用的属性和方法
$(function () { $('input').bind('click', function (e) { //接受事件对象参数 alert(e); //返回属性和方法:[object Object] }); });
(1)type获取这个事件的事件类型的字符串,例如:click
$(function () { $('input').bind('click', function (e) { alert(e.type); //返回:click(类型是string) }); });
(2)target获取触发事件的DOM元素
$(function () { $('input').bind('click', function (e) { alert(e.target); //[object HTMLInputElement] }); });
注意:target是获取触发元素的DOM,触发元素,就是你点了哪个就是哪个
(3)data获取事件调用时的额外数据
点击按钮得到数字123
$(function () { $('input').bind('click', 123, function (e) { alert(e.data); }); });
点击按钮得到字符串abc
$(function () { $('input').bind('click', 'abc', function (e) { alert(e.data); }); });
点击按钮得到数组里的a
$(function () { $('input').bind('click', [1,2,3,'a','b'], function (e) { alert(e.data[3]); //a }); });
点击按钮得到对象age里的100
$(function () { $('input').bind('click', {user : 'xixi', age : 100}, function (e) { alert(e.data.age); //100 }); });
(4)relatedTarget获取移入移出目标点离开或进入的那个DOM元素
$(function () { $('input').bind('click', function (e) { alert(e.relatedTarget); //null }); });
(5)currentTarget 获取绑定前触发的 DOM元素,等同与this
$(function () { $('input').bind('click', function (e) { alert(e.currentTarget); }); });
注意:currentTarget得到的是监听元素的DOM,而this也是得到监听元素的DOM。你绑定的哪个就是那个
(6)pageX/pageY获取相对于页面原点的水平/垂直坐标
(7)screenX/screenY获取显示器屏幕位置的水平/垂直坐标(非jQuery封装)
(8)clientX/clientY获取相对于页面视口的水平/垂直坐标(非jQuery封装)
X轴
$(function () { $(document).bind('click', function (e) { alert(e.pageX + ',' + e.screenX + ',' + e.clientX); //32,32,32 }); });
Y轴
$(function () { $(document).bind('click', function (e) { alert(e.pageY + ',' + e.screenY + ',' + e.clientY); //310,462,310 }); });
(9)result获取上一个相同事件的返回值
$(function () { $('input').bind('click', function (e) { return 123; }); $('input').bind('click', function (e) { alert(e.result); }); });
(10)timeStamp获取事件触发的时间戳(适合比较和存储)
$(function () { $('input').bind('click', function (e) { alert(e.timeStamp); }); });
(11)which获取鼠标的左中右键(1,2,3),或获取键盘按键
$(function () { $('input').bind('mousedown', function (e) { alert(e.which); }); });
(12)altKey/shiftKey和ctrlKey/metaKey获取是否按下了alt、shift、ctrl(这三个非jQuer 封装)或meta键(IE原生meta键,jQuery做了封装)
按下ctrl键点击按钮会显示true
$(function () { $('input').bind('click', function (e) { alert(e.ctrlKey); }); });
二.冒泡和默认行为
1.如果在页面中重叠了多个元素,并且重叠的这些元素都绑定了同一个事件,那么就会出现冒泡问题。
禁止冒泡
HTML页面
<body> <div style="width:200px;height:200px;background:#ccc;"> <input type="button" value="按钮" /> </div> </body>
三个不同元素触发事件阻止冒泡
$(function () { //冒泡和阻止冒泡 $('input').click(function (e) { e.stopPropagation(); //禁止冒泡 alert('input'); }); $('div').click(function (e) { e.stopPropagation(); alert('div'); }); $(document).click(function () { alert('document'); }); });
注意:当我们点击文档的时候,只触发文档事件;当我们点击div层时,触发了div和文档两个;当我们点击按钮时,触发了按钮、div 和文档。触发的顺序是从小范围到大范围。这就是所谓的冒泡现象,一层一层往上。
2.冒泡和默认行为的一些方法:
(1)preventDefault()取消某个元素的默认行为
阻止默认行为
HTML页面
<body> <div style="width:200px;height:200px;background:#ccc;"> <input type="button" value="按钮" /> <a href="http://www.baidu.com" target="_blank">百度<a> </div> </body>
点击百度弹出baidu.com阻止默认行为不跳转到http://www.baidu.com
$(function () { $('a').click(function (e) { e.preventDefault(); //阻止默认行为 alert('baidu.com'); }); });
组织表单提交
HTML页面
<body> <form action="http://www.baidu.com"> <div style="width:200px;height:200px;background:#ccc;"> <input type="submit" value="按钮" /> </div> </form> </body>
点击按钮弹出表单提交但禁止跳转到http://www.baidu.com
方式一:
$(function () { //禁止表单提交 $('input').click(function (e) { e.preventDefault(); alert('表单提交'); }); });
方式二:不弹窗组织表单提交
$(function () { //禁止表单提交 $('form').submit(function (e) { e.preventDefault(); }); });
注意:如果想让上面的超链接同时阻止默认行为且禁止冒泡行为,可以把两个方法同时写上:event.stopPropagation()和event.preventDefault()。这两个方法如果需要同时启用的时候,还有一种简写方案代替,就是直接return false。
return false阻止冒泡又禁止了默认行为
$(function () { //阻止冒泡又禁止了默认行为 $('a').click(function (e) { alert('baidu.com'); return false; }); $('div').click(function () { alert('div'); }); $(document).click(function () { alert('document'); }); });
(3)isDefaultPrevented()判断是否调用了preventDefault()方法
判断是否设定了冒泡和禁止默认行为
方式1:
$(function () { $('a').click(function (e) { e.preventDefault(); e.stopPropagation(); alert(e.isDefaultPrevented()); //true alert(e.isPropagationStopped()); //true }); });
方式2:
$(function () { $('a').click(function (e) { e.preventDefault(); e.stopPropagation(); }); $('a').click(function (e) { alert(e.isDefaultPrevented()); alert(e.isPropagationStopped()); }); });
(4)stopImmediatePropagation()取消事件冒泡,并取消该事件的后续事件处理函数
(5)isImmediatePropagationStopped()判断是否调用了stopImmediatePropagation()方法
$(function () { $('a').click(function (e) { e.stopImmediatePropagation(); // alert(e.isImmediatePropagationStopped()); //判断是否执行了stopImmediatePropagation()方法返回:true alert('a1'); //返回:a1 }); //后面的就不执行了直接跳转 $('a').click(function (e) { alert('a2'); }); $('div').click(function (e) { alert('div'); }); $(document).click(function () { alert('document'); }); });
jQuery高级事件
jQuery不但封装了大量常用的事件处理,还提供了不少高级事件方便开发者使用。比如模拟用户触发事件、事件委托事件、和统一整合的on和off,以及仅执行一次的one方法。这些方法大大降低了开发者难度,提升了开发者的开发体验。
一.模拟操作
在事件触发的时候,有时我们需要一些模拟用户行为的操作。例如:当网页加载完毕后自行点击一个按钮触发一个事件,而不是用户去点击。
<body> <input type="button" value="按钮" /> </body>
当浏览器打开的时候去自发的点击button执行了这段话
方式一:
//点击按钮事件 $(function () { $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }); //模拟用户点击操作 $('input').trigger('click'); //input元素要被模拟,模拟click点击事件 });
方式二:
$(function () { $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).trigger('click'); });
有时在模拟用户行为的时候,我们需要给事件执行传递参数,这个参数类似与event.data的额外数据,可以可以是数字、字符串、数组、对象。
trigger额外数据参数传字符串:123和abc分别对应data1,data2刷新后弹出123 | abc
$(function () { $('input').click(function (e, data1,data2) { alert(data1 + '|' + data2); }).trigger('click', ['123','abc']); }); //trigger额外数据,只有一条的时候,可以省略中括号,多条不能省略,第二条之后就无法识别了
trigger额外数据参数传数组:
$(function () { $('input').click(function (e, data1, data2, data3, data4) { alert(data1 + '|' + data2 + '|' + data3[1] + '|' + data4.user); }).trigger('click', ['123', 'abc', ['a', 'b' , 'c'], {user : 'xixi'}]); });
bind额外数据传数组:刷新弹出:123|abc|b|xixi|xixi
$(function () { $('input').bind('click', {user : 'xixi'} ,function (e, data1, data2, data3, data4) { alert(data1 + '|' + data2 + '|' + data3[1] + '|' + data4.user + '|' + e.data.user); }).trigger('click', ['123', 'abc', ['a', 'b' , 'c'], {user : 'xixi'}]); });
除了通过JavaScript事件名触发,也可以通过自定义的事件触发,所谓自定义事件其实就是一个被.bind()绑定的任意函数。
$(function () { //click,mouseover这些系统事件,自定义事件就是自己起名字的事件 $('input').bind('myEvent', function () { alert('自定义事件!'); }).trigger('myEvent'); //执行这个自定义事件(相当于调了一个函数) });
.trigger()方法提供了简写方案,只要想让某个事件执行模拟用户行为,直接再调用一个空的同名事件即可。
$(function () { $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).click(); //空的click()执行的是trigger() });
jQuery还提供了另外一个模拟用户行为的方法:.triggerHandler();这个方法的使用和.trigger()方法一样。
$(function () { $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).triggerHandler('click'); });
在常规的使用情况下,两者几乎没有区别,都是模拟用户行为,也可以可以传递额外参数。但在某些特殊情况下,就产生了差异:
区别一:.triggerHandler()方法并不会触发事件的默认行为,而.trigger()会
<body> <form action="xixi.com"> <input type="submit" value="按钮" /> </form> </body>
$(function () { //trigger提交后跳转,没有阻止默认行为 $('form').trigger('submit'); //模拟用户执行提交,并跳转到执行页面 });
$(function () { //trigger提交后没有跳转,默认行为被阻止了 $('form').triggerHandler('submit'); });
如果我们希望使用.trigger()来模拟用户提交,并且阻止事件的默认行为,则需要这么写:
$(function () { $('form').submit(function (e) { e.preventDefault(); //取消默认行为 }).trigger('submit'); });
区别二:.triggerHandler()方法只会影响第一个匹配到的元素,而.trigger()会影响所有。
<body> <input type="button" value="按钮" /> <input type="button" value="按钮" /> <input type="button" value="按钮" /> </body>
$(function () { //刷新网页.trigger()会把所有都执行一遍 $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).trigger('click'); }); $(function () { //刷新网页.triggerHandler()就执行了第一个 $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).triggerHandler('click'); });
区别三:.triggerHandler()方法会返回当前事件执行的返回值,如果没有返回值,则返回undefined;而.trigger()则返回当前包含事件触发元素的jQuery对象(方便链式连缀调用)。
$(function () { //.trigger()返回jQuery对象,可以连缀 $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); }).trigger('click').css('color','red'); });
$(function () { //.triggerHandler()返回return值,或undefined $('input').click(function () { alert('我将要使用模拟用户操作来触发!'); return 123; }).triggerHandler('click').css('color','red'); });
区别四:.trigger()在创建事件的时候,会冒泡。但这种冒泡是自定义事件才能体现出来,是jQuery扩展于DOM的机制,并非DOM特性。而.triggerHandler()不会冒泡。
<body> <div class="d1"> <div class="d2"> <div class="d3"> div </div> </div> </div> </body>
$(function () { //.trigger()会冒泡 $('div').bind('myEvent', function () { alert('自定义事件!'); }) $('.d3').trigger('myEvent'); //让d3执行自定义事件,会冒泡 });
$(function () { //.triggerHandler()不会冒泡 $('div').bind('myEvent', function () { alert('自定义事件!'); }) $('.d3').triggerHandler('myEvent'); //让d3执行自定义事件,不会冒泡 });
二.命名空间
有时,我们想对事件进行移除。但对于同名同元素绑定的事件移除往往比较麻烦,这个时候,可以使用事件的命名空间解决。
<body> <input type="button" value="按钮" /> </body>
$(function () { $('input').bind('click.abc', function () { alert('abc'); }); $('input').bind('click.xixi', function () { alert('xixi'); }); $('input').bind('mouseover.abc', function () { alert('abc'); }); $('input').unbind('click.abc'); //移除click实践中命名空间为abc的 $('input').unbind('.abc'); //移除实践中命名空间为.abc的 });
注意:也可以直接使用('.abc'),这样的话,可以移除相同命名空间的不同事件。对于模拟操作.trigger()和.triggerHandler(),用法也是一样的
三.事件委托
什么是事件委托?用现实中的理解就是:有100个学生同时在某天中午收到快递,但这100个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生。而在jQuery中,我们通过事件冒泡的特性,让子元素绑定的事件冒泡到父元素(或祖先元素)上,然后再进行相关处理即可。
如果一个企业级应用做报表处理,表格有2000行,每一行都有一个按钮处理。如果用之前的.bind()处理,那么就需要绑定2000个事件,就好比2000个学生同时站在学校门口等快递,不断会堵塞路口,还会发生各种意外。这种情况放到页面上也是一样,可能导致页面极度变慢或直接异常。而且,2000个按钮使用ajax分页的话,.bind()方法无法动态绑定尚未存在的元素。就好比,新转学的学生,快递员无法验证他的身份,就可能收不到快递。
<body> <div style="width:200px;height:200px;background:green;" id="box"> <input type="button" class="button" value="按钮" /> <input type="button" class="button" value="按钮" /> <input type="button" class="button" value="按钮" /> </div> </body>
使用.bind()不具备动态绑定功能,只有点击原始按钮才能生成
$(function () { //.bind绑定了三个事件 $('.button').bind('click',function () { alert('事件不委托!'); }); });
使用.live()永远只会绑定一个事件
$(function () { //使用live绑定的是document,而非button.所以永远只会绑定一次事件, $('.button').live('click',function () { alert('事件委托!'); }); });
使用.bind无法动态绑定事件
$(function () { $('.button').bind('click', function () { $(this).clone().appendTo('#box'); // 把自己克隆一份添加到box里 }); });
使用.live()具备动态绑定功能,jQuery1.3使用,jQuery1.7之后废弃,jQuery1.9删除
$(function () { //.live可以动态绑定事件,因为事件绑定在document上 $('.button').live('click', function () { $(this).clone().appendTo('#box'); }); }); //.live绑定在document上,而点击. button其实是冒泡到document上 //并且点击document时候,需要验证event.type和event.target才能触发
live()原理就是把 click 事件绑定到祖先元素$(document)上,而只需要给$(document)绑定一次即可,而非2000次。然后就可以处理后续动态加载的按钮的单击事件。在接受任何事件时,$(document)对象都会检查事件类型(event.type)和事件目标(event.target),如果click事件是.button,那么就执行委托给它的处理程序。.live()方法已经被删除,无法使用了。需要测试使用的话,需要引入向下兼容插件。
.live()无法使用链接连缀调用,因为参数的特性导致
$(function () { $('#box').children(0).live('click', function () { $(this).clone().appendTo('#box'); //报错 }); });
在上面的例子中,我们使用了.clone()克隆。其实如果想把事件行为复制过来,我们只需要传递 true 即可:.clone(true)。这样也能实现类似事件委托的功能,但原理却截然不同。一个是复制事件行为,一个是事件委托。而在非克隆操作下,此类功能只能使用事件委托。
$(function () { $('.button').live('click', function () { $(this).clone().appendTo('#box'); }); //当我们需要停止事件委托的时候,可以使用.die()来取消掉。 $('.button').die('click'); //和unbind一个意思 });
由于.live()和.die()在jQuery1.4.3版本中废弃了,之后推出语义清晰、减少冒泡传播层次、又支持链接连缀调用方式的方法:.delegate()和.undelegate()。但这个方法在jQuery1.7版本中被.on()方法整合替代了。
$(function () { //.live的替代方法.delegate //live语义不清晰,由于他没有指定绑定了谁,所以不清晰 //delegate语义清晰,绑定谁,谁就在开头 $('#box').delegate('.button', 'click', function () { $(this).clone().appendTo('#box'); }) //$('#box').undelegate('.button','click'); //删除 });
注意:.delegate()需要指定父元素,然后第一个参数是当前元素,第二个参数是事件方式,第三个参数是执行函数。和.bind()方法一样,可以传递额外参数。.undelegate()和.unbind()方法一样可以直接删除所有事件,比如:.undelegate('click')。也可以删除命名空间的事件,比如:.undelegate('click.abc')。
注意:.live()和.delegate()和.bind()方法一样都是事件绑定,那么区别也很明显,用途上遵循两个规则:1.在 DOM 中很多元素绑定相同事件时;2.在 DOM 中尚不存在即将生成的元素绑定事件时;我们推荐使用事件委托的绑定方式,否则推荐使用.bind()的普通绑定。
四.on、off和one
目前绑定事件和解绑的方法有三组共六个。由于这三组的共存可能会造成一定的混乱,为此jQuery1.7以后推出了.on()和.off()方法彻底摒弃前面三组。
普通绑定.bind
普通解绑.unbind
事件委托.live .delegate
解除委托.die .undelegate
新方法绑定.on
新方法解绑.off
1.新方法绑定.on替代普通绑定.bind
<body> <div style="width:200px;height:200px;background:green;" id="box"> <input type="button" class="button" value="按钮" /> </div> </body>
(1)替代.bind()方式
$(function () { //普通绑定.bind $('.button').on('click', function () { alert('替代bind'); }); });
(2)替代.bind()方式,并使用额外数据和事件对象
$(function () { //普通绑定.bind $('.button').on('click', {user : 'xixi'}, function (e) { alert('替代bind' + e.data.user); }); });
(3)替代.bind()方式,并绑定多个事件
$(function () { $('.button').on('mouseover mouseout', function (e) { alert('移入移出'); }); });
(4)替代.bind()方式,以对象模式绑定多个事件
$(function () { $('.button').on({ mouseover : function () { alert('移入'); }, mouseout : function () { alert('移出'); } }); });
~~~~
<body> <form action="xixi.html"> <div style="width:200px;height:200px;background:green;" id="box"> <input type="sumbit" class="button" value="按钮" /> </div> </form> </body>
(5)替代.bind()方式,阻止默认行为并取消冒泡
$(function () { $('form').on('submit',function () { return false; }); });
(6)替代.bind()方式,单一阻止默认行为或者单一取消冒泡可以用这个简便方法
$(function () { $('form').on('submit',false); });
2.新方法绑定.on替代普通解绑.unbind
<body> <div style="width:200px;height:200px;background:green;" id="box"> <input type="button" class="button" value="按钮" /> </div> </body>
替代.unbind()方式,移除事件
$(function () { $('.button').on('click', function () { alert('替代bind'); }); $('.button').off('click'); });
3.新方法绑定.on替代事件委托.live .delegate
$(function () { $('#box').on('click','.button',function () { $(this).clone().appendTo('#box'); }); });
4.新方法解绑.off替代解除委托.die .undelegate
$(function () { $('#box').on('click','.button',function () { $(this).clone().appendTo('#box'); }); //移出事件委托 $('#box').off('click', '.button'); });
注意:和之前方式一样,事件委托和取消事件委托也有各种搭配方式,比如额外数据、命名空间等等
不管是.bind()还是.on(),绑定事件后都不是自动移除事件的,需要通过.unbind()和.off()来手工移除。jQuery 提供了.one()方法,绑定元素执行完毕后自动移除事件,可以方法仅触发一次的事件。
$(function () { //类似于.bind()只触发一次 $('.button').one('click', function () { alert('仅一次事件触发!'); }); });
$(function () { //类似于.delegate()只触发一次 $('#box').one('click', '.button', function () { $(this).clone().appendTo('#box'); }); });