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