jquery.ba-resize.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*!
  2. * jQuery resize event - v1.1 - 3/14/2010
  3. * http://benalman.com/projects/jquery-resize-plugin/
  4. *
  5. * Copyright (c) 2010 "Cowboy" Ben Alman
  6. * Dual licensed under the MIT and GPL licenses.
  7. * http://benalman.com/about/license/
  8. */
  9. // Script: jQuery resize event
  10. //
  11. // *Version: 1.1, Last updated: 3/14/2010*
  12. //
  13. // Project Home - http://benalman.com/projects/jquery-resize-plugin/
  14. // GitHub - http://github.com/cowboy/jquery-resize/
  15. // Source - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.js
  16. // (Minified) - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.min.js (1.0kb)
  17. //
  18. // About: License
  19. //
  20. // Copyright (c) 2010 "Cowboy" Ben Alman,
  21. // Dual licensed under the MIT and GPL licenses.
  22. // http://benalman.com/about/license/
  23. //
  24. // About: Examples
  25. //
  26. // This working example, complete with fully commented code, illustrates a few
  27. // ways in which this plugin can be used.
  28. //
  29. // resize event - http://benalman.com/code/projects/jquery-resize/examples/resize/
  30. //
  31. // About: Support and Testing
  32. //
  33. // Information about what version or versions of jQuery this plugin has been
  34. // tested with, what browsers it has been tested in, and where the unit tests
  35. // reside (so you can test it yourself).
  36. //
  37. // jQuery Versions - 1.3.2, 1.4.1, 1.4.2
  38. // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1.
  39. // Unit Tests - http://benalman.com/code/projects/jquery-resize/unit/
  40. //
  41. // About: Release History
  42. //
  43. // 1.1 - (3/14/2010) Fixed a minor bug that was causing the event to trigger
  44. // immediately after bind in some circumstances. Also changed $.fn.data
  45. // to $.data to improve performance.
  46. // 1.0 - (2/10/2010) Initial release
  47. (function($,window,undefined){
  48. '$:nomunge'; // Used by YUI compressor.
  49. // A jQuery object containing all non-window elements to which the resize
  50. // event is bound.
  51. var elems = $([]),
  52. // Extend $.resize if it already exists, otherwise create it.
  53. jq_resize = $.resize = $.extend( $.resize, {} ),
  54. timeout_id,
  55. // Reused strings.
  56. str_setTimeout = 'setTimeout',
  57. str_resize = 'resize',
  58. str_data = str_resize + '-special-event',
  59. str_delay = 'delay',
  60. str_throttle = 'throttleWindow';
  61. // Property: jQuery.resize.delay
  62. //
  63. // The numeric interval (in milliseconds) at which the resize event polling
  64. // loop executes. Defaults to 250.
  65. jq_resize[ str_delay ] = 250;
  66. // Property: jQuery.resize.throttleWindow
  67. //
  68. // Throttle the native window object resize event to fire no more than once
  69. // every <jQuery.resize.delay> milliseconds. Defaults to true.
  70. //
  71. // Because the window object has its own resize event, it doesn't need to be
  72. // provided by this plugin, and its execution can be left entirely up to the
  73. // browser. However, since certain browsers fire the resize event continuously
  74. // while others do not, enabling this will throttle the window resize event,
  75. // making event behavior consistent across all elements in all browsers.
  76. //
  77. // While setting this property to false will disable window object resize
  78. // event throttling, please note that this property must be changed before any
  79. // window object resize event callbacks are bound.
  80. jq_resize[ str_throttle ] = true;
  81. // Event: resize event
  82. //
  83. // Fired when an element's width or height changes. Because browsers only
  84. // provide this event for the window element, for other elements a polling
  85. // loop is initialized, running every <jQuery.resize.delay> milliseconds
  86. // to see if elements' dimensions have changed. You may bind with either
  87. // .resize( fn ) or .bind( "resize", fn ), and unbind with .unbind( "resize" ).
  88. //
  89. // Usage:
  90. //
  91. // > jQuery('selector').bind( 'resize', function(e) {
  92. // > // element's width or height has changed!
  93. // > ...
  94. // > });
  95. //
  96. // Additional Notes:
  97. //
  98. // * The polling loop is not created until at least one callback is actually
  99. // bound to the 'resize' event, and this single polling loop is shared
  100. // across all elements.
  101. //
  102. // Double firing issue in jQuery 1.3.2:
  103. //
  104. // While this plugin works in jQuery 1.3.2, if an element's event callbacks
  105. // are manually triggered via .trigger( 'resize' ) or .resize() those
  106. // callbacks may double-fire, due to limitations in the jQuery 1.3.2 special
  107. // events system. This is not an issue when using jQuery 1.4+.
  108. //
  109. // > // While this works in jQuery 1.4+
  110. // > $(elem).css({ width: new_w, height: new_h }).resize();
  111. // >
  112. // > // In jQuery 1.3.2, you need to do this:
  113. // > var elem = $(elem);
  114. // > elem.css({ width: new_w, height: new_h });
  115. // > elem.data( 'resize-special-event', { width: elem.width(), height: elem.height() } );
  116. // > elem.resize();
  117. $.event.special[ str_resize ] = {
  118. // Called only when the first 'resize' event callback is bound per element.
  119. setup: function() {
  120. // Since window has its own native 'resize' event, return false so that
  121. // jQuery will bind the event using DOM methods. Since only 'window'
  122. // objects have a .setTimeout method, this should be a sufficient test.
  123. // Unless, of course, we're throttling the 'resize' event for window.
  124. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; }
  125. var elem = $(this);
  126. // Add this element to the list of internal elements to monitor.
  127. elems = elems.add( elem );
  128. // Initialize data store on the element.
  129. $.data( this, str_data, { w: elem.width(), h: elem.height() } );
  130. // If this is the first element added, start the polling loop.
  131. if ( elems.length === 1 ) {
  132. loopy();
  133. }
  134. },
  135. // Called only when the last 'resize' event callback is unbound per element.
  136. teardown: function() {
  137. // Since window has its own native 'resize' event, return false so that
  138. // jQuery will unbind the event using DOM methods. Since only 'window'
  139. // objects have a .setTimeout method, this should be a sufficient test.
  140. // Unless, of course, we're throttling the 'resize' event for window.
  141. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; }
  142. var elem = $(this);
  143. // Remove this element from the list of internal elements to monitor.
  144. elems = elems.not( elem );
  145. // Remove any data stored on the element.
  146. elem.removeData( str_data );
  147. // If this is the last element removed, stop the polling loop.
  148. if ( !elems.length ) {
  149. clearTimeout( timeout_id );
  150. }
  151. },
  152. // Called every time a 'resize' event callback is bound per element (new in
  153. // jQuery 1.4).
  154. add: function( handleObj ) {
  155. // Since window has its own native 'resize' event, return false so that
  156. // jQuery doesn't modify the event object. Unless, of course, we're
  157. // throttling the 'resize' event for window.
  158. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; }
  159. var old_handler;
  160. // The new_handler function is executed every time the event is triggered.
  161. // This is used to update the internal element data store with the width
  162. // and height when the event is triggered manually, to avoid double-firing
  163. // of the event callback. See the "Double firing issue in jQuery 1.3.2"
  164. // comments above for more information.
  165. function new_handler( e, w, h ) {
  166. var elem = $(this),
  167. data = $.data( this, str_data );
  168. // If called from the polling loop, w and h will be passed in as
  169. // arguments. If called manually, via .trigger( 'resize' ) or .resize(),
  170. // those values will need to be computed.
  171. data.w = w !== undefined ? w : elem.width();
  172. data.h = h !== undefined ? h : elem.height();
  173. old_handler.apply( this, arguments );
  174. };
  175. // This may seem a little complicated, but it normalizes the special event
  176. // .add method between jQuery 1.4/1.4.1 and 1.4.2+
  177. if ( $.isFunction( handleObj ) ) {
  178. // 1.4, 1.4.1
  179. old_handler = handleObj;
  180. return new_handler;
  181. } else {
  182. // 1.4.2+
  183. old_handler = handleObj.handler;
  184. handleObj.handler = new_handler;
  185. }
  186. }
  187. };
  188. function loopy() {
  189. // Start the polling loop, asynchronously.
  190. timeout_id = window[ str_setTimeout ](function(){
  191. // Iterate over all elements to which the 'resize' event is bound.
  192. elems.each(function(){
  193. var elem = $(this),
  194. width = elem.width(),
  195. height = elem.height(),
  196. data = $.data( this, str_data );
  197. // If element size has changed since the last time, update the element
  198. // data store and trigger the 'resize' event.
  199. if ( width !== data.w || height !== data.h ) {
  200. elem.trigger( str_resize, [ data.w = width, data.h = height ] );
  201. }
  202. });
  203. // Loop.
  204. loopy();
  205. }, jq_resize[ str_delay ] );
  206. };
  207. })(jQuery,this);