jQuery .on

来源:互联网 发布:现在拉货最火的软件 编辑:程序博客网 时间:2024/05/22 05:31

jQuery 1.7 于11月3日正式发布 新的事件.on()、.off()被引入。官方博客声称提升了事件委派时的性能,并给出了1.6.4 和 1.7 版本的性能比较图:


语法:

  1. $(elements).on( events [, selector] [, data] , handler );
  2. $(elements).off( [ events ] [, selector] [, handler] );

Jquery 1.6.4 bind,ubbind、live,die、delegate,delegate、one事件源码

  1. jQuery.each(["bind", "one"], function( i, name ) {
  2. jQuery.fn[ name ] = function( type, data, fn ) {
  3. var handler;
  4.  
  5. // Handle object literals
  6. if ( typeof type === "object" ) {
  7. for ( var key in type ) {
  8. this[ name ](key, data, type[key], fn);
  9. }
  10. return this;
  11. }
  12.  
  13. if ( arguments.length === 2 || data === false ) {
  14. fn = data;
  15. data = undefined;
  16. }
  17.  
  18. if ( name === "one" ) {
  19. handler = function( event ) {
  20. jQuery( this ).unbind( event, handler );
  21. return fn.apply( this, arguments );
  22. };
  23. handler.guid = fn.guid || jQuery.guid++;
  24. } else {
  25. handler = fn;
  26. }
  27.  
  28. if ( type === "unload" && name !== "one" ) {
  29. this.one( type, data, fn );
  30.  
  31. } else {
  32. for ( var i = 0, l = this.length; i < l; i++ ) {
  33. jQuery.event.add( this[i], type, handler, data );
  34. }
  35. }
  36.  
  37. return this;
  38. };
  39. });
  40.  
  41. unbind: function( type, fn ) {
  42. // Handle object literals
  43. if ( typeof type === "object" && !type.preventDefault ) {
  44. for ( var key in type ) {
  45. this.unbind(key, type[key]);
  46. }
  47.  
  48. } else {
  49. for ( var i = 0, l = this.length; i < l; i++ ) {
  50. jQuery.event.remove( this[i], type, fn );
  51. }
  52. }
  53.  
  54. return this;
  55. },
  56. jQuery.each(["live", "die"], function( i, name ) {
  57. jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
  58. var type, i = 0, match, namespaces, preType,
  59. selector = origSelector || this.selector,
  60. context = origSelector ? this : jQuery( this.context );
  61.  
  62. if ( typeof types === "object" && !types.preventDefault ) {
  63. for ( var key in types ) {
  64. context[ name ]( key, data, types[key], selector );
  65. }
  66.  
  67. return this;
  68. }
  69.  
  70. if ( name === "die" && !types &&
  71. origSelector && origSelector.charAt(0) === "." ) {
  72.  
  73. context.unbind( origSelector );
  74.  
  75. return this;
  76. }
  77.  
  78. if ( data === false || jQuery.isFunction( data ) ) {
  79. fn = data || returnFalse;
  80. data = undefined;
  81. }
  82.  
  83. types = (types || "").split(" ");
  84.  
  85. while ( (type = types[ i++ ]) != null ) {
  86. match = rnamespaces.exec( type );
  87. namespaces = "";
  88.  
  89. if ( match ) {
  90. namespaces = match[0];
  91. type = type.replace( rnamespaces, "" );
  92. }
  93.  
  94. if ( type === "hover" ) {
  95. types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
  96. continue;
  97. }
  98.  
  99. preType = type;
  100.  
  101. if ( liveMap[ type ] ) {
  102. types.push( liveMap[ type ] + namespaces );
  103. type = type + namespaces;
  104.  
  105. } else {
  106. type = (liveMap[ type ] || type) + namespaces;
  107. }
  108.  
  109. if ( name === "live" ) {
  110. // bind live handler
  111. for ( var j = 0, l = context.length; j < l; j++ ) {
  112. jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
  113. { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
  114. }
  115.  
  116. } else {
  117. // unbind live handler
  118. context.unbind( "live." + liveConvert( type, selector ), fn );
  119. }
  120. }
  121.  
  122. return this;
  123. };
  124. });
  125. delegate: function( selector, types, data, fn ) {
  126. return this.live( types, data, fn, selector );
  127. },
  128.  
  129. undelegate: function( selector, types, fn ) {
  130. if ( arguments.length === 0 ) {
  131. return this.unbind( "live" );
  132.  
  133. } else {
  134. return this.die( types, null, fn, selector );
  135. }
  136. }

Jquery 1.7 bind,ubbind、live,die、delegate,delegate、one事件源码

  1. one: function( types, selector, data, fn ) {
  2. return this.on.call( this, types, selector, data, fn, 1 );
  3. },
  4. bind: function( types, data, fn ) {
  5. return this.on( types, null, data, fn );
  6. },
  7. unbind: function( types, fn ) {
  8. return this.off( types, null, fn );
  9. },
  10.  
  11. live: function( types, data, fn ) {
  12. jQuery( this.context ).on( types, this.selector, data, fn );
  13. return this;
  14. },
  15. die: function( types, fn ) {
  16. jQuery( this.context ).off( types, this.selector || "**", fn );
  17. return this;
  18. },
  19.  
  20. delegate: function( selector, types, data, fn ) {
  21. return this.on( types, selector, data, fn );
  22. },
  23. undelegate: function( selector, types, fn ) {
  24. // ( namespace ) or ( selector, types [, fn] )
  25. return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
  26. }

源码对比中不难看出Jquery 1.7 所有的事件委派都是基于这个新引入的 .on()和.off()。性能提示了多少我们肉眼没办法察觉到,但通过源代码分析性能的提升是肯定的。

.on()和.off()事件源码

  1. on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
  2. var origFn, type;
  3. // Types can be a map of types/handlers
  4. if ( typeof types === "object" ) {
  5. // ( types-Object, selector, data )
  6. if ( typeof selector !== "string" ) {
  7. // ( types-Object, data )
  8. data = selector;
  9. selector = undefined;
  10. }
  11. for ( type in types ) {
  12. this.on( type, selector, data, types[ type ], one );
  13. }
  14. return this;
  15. }
  16.  
  17. if ( data == null && fn == null ) {
  18. // ( types, fn )
  19. fn = selector;
  20. data = selector = undefined;
  21. } else if ( fn == null ) {
  22. if ( typeof selector === "string" ) {
  23. // ( types, selector, fn )
  24. fn = data;
  25. data = undefined;
  26. } else {
  27. // ( types, data, fn )
  28. fn = data;
  29. data = selector;
  30. selector = undefined;
  31. }
  32. }
  33. if ( fn === false ) {
  34. fn = returnFalse;
  35. } else if ( !fn ) {
  36. return this;
  37. }
  38.  
  39. if ( one === 1 ) {
  40. origFn = fn;
  41. fn = function( event ) {
  42. // Can use an empty set, since event contains the info
  43. jQuery().off( event );
  44. return origFn.apply( this, arguments );
  45. };
  46. // Use same guid so caller can remove using origFn
  47. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  48. }
  49. return this.each( function() {
  50. jQuery.event.add( this, types, fn, data, selector );
  51. });
  52. },
  53. off: function( types, selector, fn ) {
  54. if ( types && types.preventDefault && types.handleObj ) {
  55. // ( event ) dispatched jQuery.Event
  56. var handleObj = types.handleObj;
  57. jQuery( types.delegateTarget ).off(
  58. handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
  59. handleObj.selector,
  60. handleObj.handler
  61. );
  62. return this;
  63. }
  64. if ( typeof types === "object" ) {
  65. // ( types-object [, selector] )
  66. for ( var type in types ) {
  67. this.off( type, selector, types[ type ] );
  68. }
  69. return this;
  70. }
  71. if ( selector === false || typeof selector === "function" ) {
  72. // ( types [, fn] )
  73. fn = selector;
  74. selector = undefined;
  75. }
  76. if ( fn === false ) {
  77. fn = returnFalse;
  78. }
  79. return this.each(function() {
  80. jQuery.event.remove( this, types, fn, selector );
  81. });
  82. }

应用举例:

  1. <button id="theone">Does nothing...</button>
  2. <button id="bind">Add Click</button>
  3. <button id="unbind">Remove Click</button>
  4. <div style="display:none;">Click!</div>
  5. <script>
  6. function aClick() {
  7. $("div").show().fadeOut("slow");
  8. }
  9. $("#bind").click(function () {
  10. $("body").on("click", "#theone", aClick)
  11. .find("#theone").text("Can Click!");
  12. });
  13. $("#unbind").click(function () {
  14. $("body").off("click", "#theone", aClick)
  15. .find("#theone").text("Does nothing...");
  16. });
  17. </script>
  18.  
  19. <p>官方推荐直接使用.on()和.off()事件,以下是新旧事件应用示例:</p>
  20. <pre>
  21. $('a').bind('click', myHandler);
  22. $('a').on('click', myHandler);
  23.  
  24. $('form').bind('submit', { val: 42 }, fn);
  25. $('form').on('submit', { val: 42 }, fn);
  26.  
  27. $(window).unbind('scroll.myPlugin');
  28. $(window).off('scroll.myPlugin');
  29.  
  30. $('.comment').delegate('a.add', 'click', addNew);
  31. $('.comment').on('click', 'a.add', addNew);
  32.  
  33. $('.dialog').undelegate('a', 'click.myDlg');
  34. $('.dialog').off('click.myDlg', 'a');
  35.  
  36. $('a').live('click', fn);
  37. $(document).on('click', 'a', fn);
  38.  
  39. $('a').die('click');
  40. $(document).off('click', 'a');