经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
jQuery 源码分析(十七) 事件系统模块 实例方法和便捷方法 详解
来源:cnblogs  作者:大沙漠  时间:2019/10/30 9:14:37  对本文有异议

实例方法和便捷方法是指jQuery可以直接通过链接操作的方法,是通过调用$.event上的方法(上一节介绍的底层方法)来实现的,常用的如下:

  • on(types,selector,data,fn,one)  ;为匹配元素集合中的每个元素绑定一个或多个类型的事件监听函数
    • types          ;事件类型字符串,多个事件类型之间用空格隔开
    • selector      ;可选,是一个选择器表达式字符串,用于绑定代理事件。
    • data            ;传递给事件监听函数的自定义数据,可以是任何类型。
    • fn           ;待绑定的监听函数
    • one                  ;该事件是否只执行一次,为方法.one()提供支持

     writer by:大沙漠 QQ:22969969

  • off(types,selector,fn)  ;移除匹配元素中每个元素上绑定的一个或多个类型的监听函数,参数如下:
    • types               ;一个或多个以空格分隔的事件类型和可选的命名空间
    • selector           ;可选的选择器表达式字符串,用于移除代理事件
    • fn                    ;待移除的监听函数,可以设置为false,表示内部定义的只返回false的函数
  • off(types,selector,fn)   ;移除匹配元素中每个元素上绑定的一个或多个类型的监听函数
    • types        ;一个或多个以空格分隔的事件类型和可选的命名空间
    • selector    ;可选的选择器表达式字符串,用于移除代理事件
    • fn          ;待移除的监听函数,可以设置为false
  • bind(types,data,fn)            ;绑定一个普通事件
  • trigger(type, data)                  执行每个匹配元素上绑定的监听函数和默认行为,并模拟冒泡过程
  • one(types,selector,data,fn)    ;为匹配元素集合中的每个元素绑定最多执行一次的事件监听函数
  • hover(fnOver, fnOut)              ;用于在匹配元素上绑定一个或两个监听函数,当鼠标指针进入和离开时,绑定的监听函数被执行

我们还是以上一节的实例为例,用实例方法改写一下,如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
  7. <style>div{width: 200px;padding-top:50px;height: 150px;background: #ced;}div button{margin:0 auto;display: block;}</style>
  8. </head>
  9. <body>
  10. <div>
  11. <button id="button">按钮1</button>
  12. </div>
  13. <script>
  14. $("div").on('click',()=>console.log('div普通单击事件'));
  15. $('div').on('click','button',()=>console.log('d1代理事件'))
  16. </script>
  17. </body>
  18. </html>

渲染如下:

和上一节一样,我们在div上绑定了一个普通事件和代理事件,当点击div时触发普通事件,点击按钮时分别触发普通事件和代理事件。

另外为了更方变使用事件,jQuery还定义了很多的便捷事件方法,可以直接在jQuery实例上调用,注意:便捷方法不能绑定代理事件,只能绑定普通事件,所有的便捷方法如下:

blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu

我们将上面的例子改写一下,用便捷方法来实现,如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
  7. <style>div{width: 200px;padding-top:50px;height: 150px;background: #ced;}div button{margin:0 auto;display: block;}</style>
  8. </head>
  9. <body>
  10. <div>
  11. <button id="button">按钮1</button>
  12. </div>
  13. <script>
  14. $("div").click(()=>console.log('div普通单击事件')); //用便捷事件来实现
  15. $('div').on('click','button',()=>console.log('d1代理事件')) //代理事件不能用便捷方法来操作,因此我们用实例方法来实现
  16. </script>
  17. </body>
  18. </html>

效果和上面是一样的。

 

源码分析


实例方法是定义在jQuery.fn上的,on主要对参数做一些判断,以支持多种格式的调用方法,实现如下:

  1. jQuery.fn.extend({
  2. on: function( types, selector, data, fn, /*INTERNAL*/ one ) { //该方法主要是修正参数。为匹配元素集合中的每个元素绑定一个或多个类型的事件监听函数。
  3. var origFn, type;
  4. // Types can be a map of types/handlers //如果types是对象时,即参数格式是.on(Object,selector,data,one)或.one(Object,data,one)则
  5. if ( typeof types === "object" ) {
  6. // ( types-Object, selector, data )
  7. if ( typeof selector !== "string" ) {
  8. // ( types-Object, data )
  9. data = selector;
  10. selector = undefined;
  11. }
  12. for ( type in types ) { //遍历参数types,递归调用方法.on(types,selector,data,fn,one)绑定事件。
  13. this.on( type, selector, data, types[ type ], one );
  14. }
  15. return this;
  16. }
  17. if ( data == null && fn == null ) { //如果没有参数3、4,则认为格式是.on(types,fn)
  18. // ( types, fn )
  19. fn = selector; //把第二个参数修正为fn。
  20. data = selector = undefined;
  21. } else if ( fn == null ) { //传入了三个参数时
  22. if ( typeof selector === "string" ) { //如果第二个参数是字符串,则认为格式是:.on(types,selector,fn) 忽略参数data,并把第三个参数作为参数fn。
  23. // ( types, selector, fn )
  24. fn = data;
  25. data = undefined;
  26. } else { //否则则认为忽略参数selector,并把第而个参数作为参数data,并把第三个参数作为参数fn。格式是.on(types,data,fn)
  27. // ( types, data, fn )
  28. fn = data;
  29. data = selector;
  30. selector = undefined;
  31. }
  32. }
  33. if ( fn === false ) { //如果参数fn是布尔值false,则把它修正为总返回false的函数returnFalse()。
  34. fn = returnFalse;
  35. } else if ( !fn ) { //如果fn没有值则直接返回。
  36. return this;
  37. }
  38. if ( one === 1 ) { //当方法one()调用.on()时,该参数为1,就会把监听函数fn重新封装为一个只会执行一次的新监听函数。
  39. origFn = fn;
  40. fn = function( event ) {
  41. // Can use an empty set, since event contains the info
  42. jQuery().off( event );
  43. return origFn.apply( this, arguments );
  44. };
  45. // Use same guid so caller can remove using origFn
  46. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  47. }
  48. return this.each( function() { //遍历当前的this
  49. jQuery.event.add( this, types, fn, data, selector ); //调用add()绑定事件
  50. });
  51. },
  52. one: function( types, selector, data, fn ) { //为匹配元素集合中的每个元素绑定一个或多个类型的事件监听函数,每个监听函数在每个匹配元素上最多执行一次。该方法简单的通过调用.on(types,selector,data,fn,one)来实现。
  53. return this.on.call( this, types, selector, data, fn, 1 );
  54. },
  55. /**/
  56. })

对于便捷方法来说,他就是在$.fn上定义每一个属性,值为一个函数,内部还是调用$.fn.on来实现添加事件的,如下:

  1. jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
  2. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  3. "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { //参数1是一个数组 参数2是个函数,其中name是值,比如blur、focus
  4.  
  5. // Handle event binding
  6. jQuery.fn[ name ] = function( data, fn ) { //初始化事件便捷方法,在jQuery.fn对象上添加元素,这样jQuery实例就可以直接访问了
  7. if ( fn == null ) { //修正参数,如果只传入一个参数,则把该参数视为fn参数,把data视为null
  8. fn = data;
  9. data = null;
  10. }
  11. return arguments.length > 0 ? //根据参数个数决定是绑定事件还是触发事件
  12. this.on( name, null, data, fn ) : //如果参数个数大于1,则调用方法.on()绑定事件监听函数
  13. this.trigger( name ); //如果没有参数,则调用方法.trigger()触发事件监听函数和默认行为
  14. };
  15. if ( jQuery.attrFn ) { //记录事件便捷方法名,在调用jQuery.attr()读取或设置HTML属性时,如果属性名与事件便捷方法名同名,则会改为调用同名的事件便捷方法a
  16. jQuery.attrFn[ name ] = true;
  17. }
  18. if ( rkeyEvent.test( name ) ) {
  19. jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
  20. }
  21. if ( rmouseEvent.test( name ) ) {
  22. jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
  23. }
  24. });

可以看到,如果执行便捷方法时不传递参数将触发该事件,例如:$('div').click()将会触发在该div上绑定的普通事件。

原文链接:http://www.cnblogs.com/greatdesert/p/11679507.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号