jquery.tinyscrollbar.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. ;(function (factory)
  2. {
  3. if (typeof define === 'function' && define.amd)
  4. {
  5. define(['jquery'], factory);
  6. }
  7. else if (typeof exports === 'object')
  8. {
  9. factory(require('jquery'));
  10. }
  11. else
  12. {
  13. factory(jQuery);
  14. }
  15. }
  16. (function ($)
  17. {
  18. "use strict";
  19. var pluginName = "tinyscrollbar"
  20. , defaults =
  21. {
  22. axis : 'y' // Vertical or horizontal scrollbar? ( x || y ).
  23. , wheel : true // Enable or disable the mousewheel;
  24. , wheelSpeed : 40 // How many pixels must the mouswheel scroll at a time.
  25. , wheelLock : true // Lock default scrolling window when there is no more content.
  26. , scrollInvert : false // Enable invert style scrolling
  27. , trackSize : false // Set the size of the scrollbar to auto or a fixed number.
  28. , thumbSize : false // Set the size of the thumb to auto or a fixed number.
  29. }
  30. ;
  31. function Plugin($container, options)
  32. {
  33. this.options = $.extend({}, defaults, options);
  34. this._defaults = defaults;
  35. this._name = pluginName;
  36. var self = this
  37. , $viewport = $container.find(".viewport")
  38. , $overview = $container.find(".overview")
  39. , $scrollbar = $container.find(".scrollbar")
  40. , $track = $scrollbar.find(".track")
  41. , $thumb = $scrollbar.find(".thumb")
  42. , mousePosition = 0
  43. , isHorizontal = this.options.axis === 'x'
  44. , hasTouchEvents = ("ontouchstart" in document.documentElement)
  45. , wheelEvent = ("onwheel" in document || document.documentMode >= 9) ? "wheel" :
  46. (document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll")
  47. , sizeLabel = isHorizontal ? "width" : "height"
  48. , posiLabel = isHorizontal ? "left" : "top"
  49. ;
  50. this.contentPosition = 0;
  51. this.viewportSize = 0;
  52. this.contentSize = 0;
  53. this.contentRatio = 0;
  54. this.trackSize = 0;
  55. this.trackRatio = 0;
  56. this.thumbSize = 0;
  57. this.thumbPosition = 0;
  58. function initialize()
  59. {
  60. self.update();
  61. setEvents();
  62. return self;
  63. }
  64. this.update = function(scrollTo)
  65. {
  66. var sizeLabelCap = sizeLabel.charAt(0).toUpperCase() + sizeLabel.slice(1).toLowerCase();
  67. this.viewportSize = $viewport[0]['offset'+ sizeLabelCap];
  68. this.contentSize = $overview[0]['scroll'+ sizeLabelCap];
  69. this.contentRatio = this.viewportSize / this.contentSize;
  70. this.trackSize = this.options.trackSize || this.viewportSize;
  71. this.thumbSize = Math.min(this.trackSize, Math.max(0, (this.options.thumbSize || (this.trackSize * this.contentRatio))));
  72. this.trackRatio = this.options.thumbSize ? (this.contentSize - this.viewportSize) / (this.trackSize - this.thumbSize) : (this.contentSize / this.trackSize);
  73. $scrollbar.toggleClass("disable", this.contentRatio >= 1);
  74. switch (scrollTo)
  75. {
  76. case "bottom":
  77. this.contentPosition = this.contentSize - this.viewportSize;
  78. break;
  79. case "relative":
  80. this.contentPosition = Math.min(this.contentSize - this.viewportSize, Math.max(0, this.contentPosition));
  81. break;
  82. default:
  83. this.contentPosition = parseInt(scrollTo, 10) || 0;
  84. }
  85. setSize();
  86. return self;
  87. };
  88. function setSize()
  89. {
  90. $thumb.css(posiLabel, self.contentPosition / self.trackRatio);
  91. $overview.css(posiLabel, -self.contentPosition);
  92. $scrollbar.css(sizeLabel, self.trackSize);
  93. $track.css(sizeLabel, self.trackSize);
  94. $thumb.css(sizeLabel, self.thumbSize);
  95. }
  96. function setEvents()
  97. {
  98. if(hasTouchEvents)
  99. {
  100. $viewport[0].ontouchstart = function(event)
  101. {
  102. if(1 === event.touches.length)
  103. {
  104. event.stopPropagation();
  105. start(event.touches[0]);
  106. }
  107. };
  108. }
  109. else
  110. {
  111. $thumb.bind("mousedown", start);
  112. $track.bind("mousedown", drag);
  113. }
  114. $(window).resize(function()
  115. {
  116. self.update("relative");
  117. });
  118. if(self.options.wheel && window.addEventListener)
  119. {
  120. $container[0].addEventListener(wheelEvent, wheel, false );
  121. }
  122. else if(self.options.wheel)
  123. {
  124. $container[0].onmousewheel = wheel;
  125. }
  126. }
  127. function start(event)
  128. {
  129. $("body").addClass("noSelect");
  130. mousePosition = isHorizontal ? event.pageX : event.pageY;
  131. self.thumbPosition = parseInt($thumb.css(posiLabel), 10) || 0;
  132. if(hasTouchEvents)
  133. {
  134. document.ontouchmove = function(event)
  135. {
  136. event.preventDefault();
  137. drag(event.touches[0]);
  138. };
  139. document.ontouchend = end;
  140. }
  141. else
  142. {
  143. $(document).bind("mousemove", drag);
  144. $(document).bind("mouseup", end);
  145. $thumb.bind("mouseup", end);
  146. }
  147. }
  148. function wheel(event)
  149. {
  150. if(self.contentRatio < 1)
  151. {
  152. var evntObj = event || window.event
  153. , deltaDir = "delta" + self.options.axis.toUpperCase()
  154. , wheelSpeedDelta = -(evntObj[deltaDir] || evntObj.detail || (-1 / 3 * evntObj.wheelDelta)) / 40
  155. ;
  156. self.contentPosition -= wheelSpeedDelta * self.options.wheelSpeed;
  157. self.contentPosition = Math.min((self.contentSize - self.viewportSize), Math.max(0, self.contentPosition));
  158. $container.trigger("move");
  159. $thumb.css(posiLabel, self.contentPosition / self.trackRatio);
  160. $overview.css(posiLabel, -self.contentPosition);
  161. if(self.options.wheelLock || (self.contentPosition !== (self.contentSize - self.viewportSize) && self.contentPosition !== 0))
  162. {
  163. evntObj = $.event.fix(evntObj);
  164. evntObj.preventDefault();
  165. }
  166. }
  167. }
  168. function drag(event)
  169. {
  170. if(self.contentRatio < 1)
  171. {
  172. var mousePositionNew = isHorizontal ? event.pageX : event.pageY
  173. , thumbPositionDelta = mousePositionNew - mousePosition
  174. ;
  175. if(self.options.scrollInvert && hasTouchEvents)
  176. {
  177. thumbPositionDelta = mousePosition - mousePositionNew;
  178. }
  179. var thumbPositionNew = Math.min((self.trackSize - self.thumbSize), Math.max(0, self.thumbPosition + thumbPositionDelta));
  180. self.contentPosition = thumbPositionNew * self.trackRatio;
  181. $container.trigger("move");
  182. $thumb.css(posiLabel, thumbPositionNew);
  183. $overview.css(posiLabel, -self.contentPosition);
  184. }
  185. }
  186. function end()
  187. {
  188. $("body").removeClass("noSelect");
  189. $(document).unbind("mousemove", drag);
  190. $(document).unbind("mouseup", end);
  191. $thumb.unbind("mouseup", end);
  192. document.ontouchmove = document.ontouchend = null;
  193. }
  194. return initialize();
  195. }
  196. $.fn[pluginName] = function(options)
  197. {
  198. return this.each(function()
  199. {
  200. if(!$.data(this, "plugin_" + pluginName))
  201. {
  202. $.data(this, "plugin_" + pluginName, new Plugin($(this), options));
  203. }
  204. });
  205. };
  206. }));