1;(function(factory) { 2 if (typeof define === 'function' && define.amd) { 3 define(['jquery'], factory); 4 } 5 else if (typeof exports === 'object') { 6 module.exports = factory(require("jquery")); 7 } 8 else { 9 factory(jQuery); 10 } 11} 12(function($) { 13 "use strict"; 14 15 var pluginName = "tinyscrollbar" 16 , defaults = { 17 axis : 'y' 18 , wheel : true 19 , wheelSpeed : 40 20 , wheelLock : true 21 , touchLock : true 22 , trackSize : false 23 , thumbSize : false 24 , thumbSizeMin : 20 25 } 26 ; 27 28 function Plugin($container, options) { 29 /** 30 * The options of the carousel extend with the defaults. 31 * 32 * @property options 33 * @type Object 34 */ 35 this.options = $.extend({}, defaults, options); 36 37 /** 38 * @property _defaults 39 * @type Object 40 * @private 41 * @default defaults 42 */ 43 this._defaults = defaults; 44 45 /** 46 * @property _name
47 * @type String 48 * @private 49 * @final 50 * @default 'tinyscrollbar' 51 */ 52 this._name = pluginName; 53 54 var self = this 55 , $viewport = $container.find(".viewport") 56 , $overview = $container.find(".overview") 57 , $scrollbar = $container.find(".scrollbar") 58 , $track = $scrollbar.find(".track") 59 , $thumb = $scrollbar.find(".thumb") 60 61 , hasTouchEvents = ("ontouchstart" in document.documentElement) 62 , wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel" 63 document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel" 64 "DOMMouseScroll" // let's assume that remaining browsers are older Firefox 65 , isHorizontal = this.options.axis === 'x' 66 , sizeLabel = isHorizontal ? "width" : "height" 67 , posiLabel = isHorizontal ? "left" : "top" 68 69 , mousePosition = 0 70 ; 71 72 /** 73 * The position of the content relative to the viewport. 74 * 75 * @property contentPosition 76 * @type Number 77 */ 78 this.contentPosition = 0; 79 80 /** 81 * The height or width of the viewport. 82 * 83 * @property viewportSize 84 * @type Number 85 */ 86 this.viewportSize = 0; 87 88 /** 89 * The height or width of the content. 90 * 91 * @property contentSize 92 * @type Number 93 */ 94 this.contentSize = 0; 95 96 /** 97 * The ratio of the content size relative to the viewport size. 98 * 99 * @property contentRatio 100 * @type Number 101 */ 102 this.contentRatio = 0; 103 104 /** 105 * The height or width of the content. 106 * 107 * @property trackSize 108 * @type Number 109 */ 110 this.trackSize = 0; 111 112 /** 113 * The size of the track relative to the size of the content. 114 * 115 * @property trackRatio 116 * @type Number 117 */ 118 this.trackRatio = 0; 119 120 /** 121 * The height or width of the thumb. 122 * 123 * @property thumbSize 124 * @type Number 125 */ 126 this.thumbSize = 0; 127 128 /** 129 * The position of the thumb relative to the track. 130 * 131 * @property thumbPosition 132 * @type Number 133 */ 134 this.thumbPosition = 0; 135 136 /** 137 * Will be true if there is content to scroll. 138 * 139 * @property hasContentToSroll 140 * @type Boolean 141 */ 142 this.hasContentToSroll = false; 143 144 /** 145 * @method _initialize 146 * @private 147 */ 148 function _initialize() { 149 self.update(); 150 _setEvents(); 151 152 return self; 153 } 154 155 /** 156 * You can use the update method to adjust the scrollbar to new content or to move the scrollbar to a certain point. 157 * 158 * @method update 159 * @chainable 160 * @param {Number|String} [scrollTo] Number in pixels or the values "relative" or "bottom". If you dont specify a parameter it will default to top 161 */ 162 this.update = function(scrollTo) { 163 var sizeLabelCap = sizeLabel.charAt(0).toUpperCase() + sizeLabel.slice(1).toLowerCase(); 164 this.viewportSize = $viewport[0]['offset'+ sizeLabelCap]; 165 this.contentSize = $overview[0]['scroll'+ sizeLabelCap]; 166 this.contentRatio = this.viewportSize / this.contentSize; 167 this.trackSize = this.options.trackSize || this.viewportSize; 168 this.thumbSize = Math.min(this.trackSize, Math.max(this.options.thumbSizeMin, (this.options.thumbSize || (this.trackSize * this.contentRatio)))); 169 this.trackRatio = (this.contentSize - this.viewportSize) / (this.trackSize - this.thumbSize); 170 this.hasContentToSroll = this.contentRatio < 1; 171 172 $scrollbar.toggleClass("disable", !this.hasContentToSroll); 173 174 switch (scrollTo) { 175 case "bottom": 176 this.contentPosition = Math.max(this.contentSize - this.viewportSize, 0); 177 break; 178 179 case "relative": 180 this.contentPosition = Math.min(Math.max(this.contentSize - this.viewportSize, 0), Math.max(0, this.contentPosition)); 181 break; 182 183 default: 184 this.contentPosition = parseInt(scrollTo, 10) || 0; 185 } 186 187 this.thumbPosition = this.contentPosition / this.trackRatio; 188 189 _setCss(); 190 191 return self; 192 }; 193 194 /** 195 * @method _setCss 196 * @private 197 */ 198 function _setCss() { 199 $thumb.css(posiLabel, self.thumbPosition); 200 $overview.css(posiLabel, -self.contentPosition); 201 $scrollbar.css(sizeLabel, self.trackSize); 202 $track.css(sizeLabel, self.trackSize); 203 $thumb.css(sizeLabel, self.thumbSize); 204 } 205 206 /** 207 * @method _setEvents 208 * @private 209 */ 210 function _setEvents() { 211 if(hasTouchEvents) { 212 $viewport[0].ontouchstart = function(event) { 213 if(1 === event.touches.length) { 214 event.stopPropagation(); 215 216 _start(event.touches[0]); 217 } 218 }; 219 } 220 $thumb.bind("mousedown", function(event){ 221 event.stopPropagation(); 222 _start(event); 223 }); 224 $track.bind("mousedown", function(event){ 225 _start(event, true); 226 }); 227 228 $(window).resize(function() { 229 self.update("relative"); 230 }); 231 232 if(self.options.wheel && window.addEventListener) { 233 $container[0].addEventListener(wheelEvent, _wheel, false); 234 } 235 else if(self.options.wheel) { 236 $container[0].onmousewheel = _wheel; 237 } 238 } 239 240 /** 241 * @method _isAtBegin 242 * @private 243 */ 244 function _isAtBegin() { 245 return self.contentPosition > 0; 246 } 247 248 /** 249 * @method _isAtEnd 250 * @private 251 */ 252 function _isAtEnd() { 253 return self.contentPosition <= (self.contentSize - self.viewportSize) - 5; 254 } 255 256 /** 257 * @method _start 258 * @private 259 */ 260 function _start(event, gotoMouse) { 261 if(self.hasContentToSroll) { 262 $("body").addClass("noSelect"); 263 264 mousePosition = gotoMouse ? $thumb.offset()[posiLabel] : (isHorizontal ? event.pageX : event.pageY); 265 266 if(hasTouchEvents) { 267 document.ontouchmove = function(event) { 268 if(self.options.touchLock || _isAtBegin() && _isAtEnd()) { 269 event.preventDefault(); 270 } 271 event.touches[0][pluginName + "Touch"] = 1; 272 _drag(event.touches[0]); 273 }; 274 document.ontouchend = _end; 275 } 276 $(document).bind("mousemove", _drag); 277 $(document).bind("mouseup", _end); 278 $thumb.bind("mouseup", _end); 279 $track.bind("mouseup", _end); 280 281 _drag(event); 282 } 283 } 284 285 /** 286 * @method _wheel 287 * @private 288 */ 289 function _wheel(event) { 290 if(self.hasContentToSroll) { 291 // Trying to make sense of all the different wheel event implementations.. 292 // 293 var evntObj = event || window.event 294 , wheelDelta = -(evntObj.deltaY || evntObj.detail || (-1 / 3 * evntObj.wheelDelta)) / 40 295 , multiply = (evntObj.deltaMode === 1) ? self.options.wheelSpeed : 1 296 ; 297 298 self.contentPosition -= wheelDelta * multiply * self.options.wheelSpeed; 299 self.contentPosition = Math.min((self.contentSize - self.viewportSize), Math.max(0, self.contentPosition)); 300 self.thumbPosition = self.contentPosition / self.trackRatio; 301 302 /** 303 * The move event will trigger when the carousel slides to a new slide. 304 * 305 * @event move 306 */ 307 $container.trigger("move"); 308 309 $thumb.css(posiLabel, self.thumbPosition); 310 $overview.css(posiLabel, -self.contentPosition); 311 312 if(self.options.wheelLock || _isAtBegin() && _isAtEnd()) { 313 evntObj = $.event.fix(evntObj); 314 evntObj.preventDefault(); 315 } 316 } 317 event.stopPropagation(); 318 } 319 320 /** 321 * @method _drag 322 * @private 323 */ 324 function _drag(event) { 325 if(self.hasContentToSroll) { 326 var mousePositionNew = isHorizontal ? event.pageX : event.pageY 327 , thumbPositionDelta = event[pluginName + "Touch"] ? 328 (mousePosition - mousePositionNew) : (mousePositionNew - mousePosition) 329 , thumbPositionNew = Math.min((self.trackSize - self.thumbSize), Math.max(0, self.thumbPosition + thumbPositionDelta)) 330 ; 331 332 self.contentPosition = thumbPositionNew * self.trackRatio; 333 334 $container.trigger("move"); 335 336 $thumb.css(posiLabel, thumbPositionNew); 337 $overview.css(posiLabel, -self.contentPosition); 338 } 339 } 340 341 /** 342 * @method _end 343 * @private 344 */ 345 function _end() { 346 self.thumbPosition = parseInt($thumb.css(posiLabel), 10) || 0; 347 348 $("body").removeClass("noSelect"); 349 $(document).unbind("mousemove", _drag); 350 $(document).unbind("mouseup", _end); 351 $thumb.unbind("mouseup", _end); 352 $track.unbind("mouseup", _end); 353 document.ontouchmove = document.ontouchend = null; 354 } 355 356 return _initialize(); 357 } 358 359 /** 360 * @class tinyscrollbar 361 * @constructor 362 * @param {Object} options 363 @param {String} [options.axis='y'] Vertical or horizontal scroller? ( x || y ). 364 @param {Boolean} [options.wheel=true] Enable or disable the mousewheel. 365 @param {Boolean} [options.wheelSpeed=40] How many pixels must the mouswheel scroll at a time. 366 @param {Boolean} [options.wheelLock=true] Lock default window wheel scrolling when there is no more content to scroll. 367 @param {Number} [options.touchLock=true] Lock default window touch scrolling when there is no more content to scroll. 368 @param {Boolean|Number} [options.trackSize=false] Set the size of the scrollbar to auto(false) or a fixed number. 369 @param {Boolean|Number} [options.thumbSize=false] Set the size of the thumb to auto(false) or a fixed number 370 @param {Boolean} [options.thumbSizeMin=20] Minimum thumb size. 371 */ 372 $.fn[pluginName] = function(options) { 373 return this.each(function() { 374 if(!$.data(this, "plugin_" + pluginName)) { 375 $.data(this, "plugin_" + pluginName, new Plugin($(this), options)); 376 } 377 }); 378 }; 379}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.