You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

202 line
7.2 KiB

  1. /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
  2. * Licensed under the MIT License (LICENSE.txt).
  3. *
  4. * Version: 3.1.9
  5. *
  6. * Requires: jQuery 1.2.2+
  7. */
  8. (function (factory) {
  9. if ( typeof define === 'function' && define.amd ) {
  10. // AMD. Register as an anonymous module.
  11. define(['jquery'], factory);
  12. } else if (typeof exports === 'object') {
  13. // Node/CommonJS style for Browserify
  14. module.exports = factory;
  15. } else {
  16. // Browser globals
  17. factory(jQuery);
  18. }
  19. }(function ($) {
  20. var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
  21. toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
  22. ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
  23. slice = Array.prototype.slice,
  24. nullLowestDeltaTimeout, lowestDelta;
  25. if ( $.event.fixHooks ) {
  26. for ( var i = toFix.length; i; ) {
  27. $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
  28. }
  29. }
  30. var special = $.event.special.mousewheel = {
  31. version: '3.1.9',
  32. setup: function() {
  33. if ( this.addEventListener ) {
  34. for ( var i = toBind.length; i; ) {
  35. this.addEventListener( toBind[--i], handler, false );
  36. }
  37. } else {
  38. this.onmousewheel = handler;
  39. }
  40. // Store the line height and page height for this particular element
  41. $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
  42. $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
  43. },
  44. teardown: function() {
  45. if ( this.removeEventListener ) {
  46. for ( var i = toBind.length; i; ) {
  47. this.removeEventListener( toBind[--i], handler, false );
  48. }
  49. } else {
  50. this.onmousewheel = null;
  51. }
  52. },
  53. getLineHeight: function(elem) {
  54. return parseInt($(elem)['offsetParent' in $.fn ? 'offsetParent' : 'parent']().css('fontSize'), 10);
  55. },
  56. getPageHeight: function(elem) {
  57. return $(elem).height();
  58. },
  59. settings: {
  60. adjustOldDeltas: true
  61. }
  62. };
  63. $.fn.extend({
  64. mousewheel: function(fn) {
  65. return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
  66. },
  67. unmousewheel: function(fn) {
  68. return this.unbind('mousewheel', fn);
  69. }
  70. });
  71. function handler(event) {
  72. var orgEvent = event || window.event,
  73. args = slice.call(arguments, 1),
  74. delta = 0,
  75. deltaX = 0,
  76. deltaY = 0,
  77. absDelta = 0;
  78. event = $.event.fix(orgEvent);
  79. event.type = 'mousewheel';
  80. // Old school scrollwheel delta
  81. if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
  82. if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
  83. if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
  84. if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
  85. // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
  86. if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
  87. deltaX = deltaY * -1;
  88. deltaY = 0;
  89. }
  90. // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
  91. delta = deltaY === 0 ? deltaX : deltaY;
  92. // New school wheel delta (wheel event)
  93. if ( 'deltaY' in orgEvent ) {
  94. deltaY = orgEvent.deltaY * -1;
  95. delta = deltaY;
  96. }
  97. if ( 'deltaX' in orgEvent ) {
  98. deltaX = orgEvent.deltaX;
  99. if ( deltaY === 0 ) { delta = deltaX * -1; }
  100. }
  101. // No change actually happened, no reason to go any further
  102. if ( deltaY === 0 && deltaX === 0 ) { return; }
  103. // Need to convert lines and pages to pixels if we aren't already in pixels
  104. // There are three delta modes:
  105. // * deltaMode 0 is by pixels, nothing to do
  106. // * deltaMode 1 is by lines
  107. // * deltaMode 2 is by pages
  108. if ( orgEvent.deltaMode === 1 ) {
  109. var lineHeight = $.data(this, 'mousewheel-line-height');
  110. delta *= lineHeight;
  111. deltaY *= lineHeight;
  112. deltaX *= lineHeight;
  113. } else if ( orgEvent.deltaMode === 2 ) {
  114. var pageHeight = $.data(this, 'mousewheel-page-height');
  115. delta *= pageHeight;
  116. deltaY *= pageHeight;
  117. deltaX *= pageHeight;
  118. }
  119. // Store lowest absolute delta to normalize the delta values
  120. absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
  121. if ( !lowestDelta || absDelta < lowestDelta ) {
  122. lowestDelta = absDelta;
  123. // Adjust older deltas if necessary
  124. if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
  125. lowestDelta /= 40;
  126. }
  127. }
  128. // Adjust older deltas if necessary
  129. if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
  130. // Divide all the things by 40!
  131. delta /= 40;
  132. deltaX /= 40;
  133. deltaY /= 40;
  134. }
  135. // Get a whole, normalized value for the deltas
  136. delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
  137. deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
  138. deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
  139. // Add information to the event object
  140. event.deltaX = deltaX;
  141. event.deltaY = deltaY;
  142. event.deltaFactor = lowestDelta;
  143. // Go ahead and set deltaMode to 0 since we converted to pixels
  144. // Although this is a little odd since we overwrite the deltaX/Y
  145. // properties with normalized deltas.
  146. event.deltaMode = 0;
  147. // Add event and delta to the front of the arguments
  148. args.unshift(event, delta, deltaX, deltaY);
  149. // Clearout lowestDelta after sometime to better
  150. // handle multiple device types that give different
  151. // a different lowestDelta
  152. // Ex: trackpad = 3 and mouse wheel = 120
  153. if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
  154. nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
  155. return ($.event.dispatch || $.event.handle).apply(this, args);
  156. }
  157. function nullLowestDelta() {
  158. lowestDelta = null;
  159. }
  160. function shouldAdjustOldDeltas(orgEvent, absDelta) {
  161. // If this is an older event and the delta is divisable by 120,
  162. // then we are assuming that the browser is treating this as an
  163. // older mouse wheel event and that we should divide the deltas
  164. // by 40 to try and get a more usable deltaFactor.
  165. // Side note, this actually impacts the reported scroll distance
  166. // in older browsers and can cause scrolling to be slower than native.
  167. // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
  168. return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
  169. }
  170. }));