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