1/* 2== malihu jquery custom scrollbars plugin == 3version: 2.3.2 4author: malihu (http://manos.malihu.gr) 5plugin home: http://manos.malihu.gr/jquery-custom-content-scroller 6*/ 7(function($){ 8 var methods={ 9 init:function(options){ 10 var defaults={ 11 set_width:false, /*optional element width: boolean, pixels, percentage*/ 12 set_height:false, /*optional element height: boolean, pixels, percentage*/ 13 horizontalScroll:false, /*scroll horizontally: boolean*/ 14 scrollInertia:550, /*scrolling inertia: integer (milliseconds)*/ 15 scrollEasing:"easeOutCirc", /*scrolling easing: string*/ 16 mouseWheel:"pixels", /*mousewheel support and velocity: boolean, "auto", integer, "pixels"*/ 17 mouseWheelPixels:60, /*mousewheel pixels amount: integer*/ 18 autoDraggerLength:true, /*auto-adjust scrollbar dragger length: boolean*/ 19 scrollButtons:{ /*scroll buttons*/ 20 enable:false, /*scroll buttons support: boolean*/ 21 scrollType:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/ 22 scrollSpeed:20, /*scroll buttons continuous scrolling speed: integer*/ 23 scrollAmount:40 /*scroll buttons pixels scroll amount: integer (pixels)*/ 24 }, 25 advanced:{ 26 updateOnBrowserResize:true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/ 27 updateOnContentResize:false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/ 28 autoExpandHorizontalScroll:false, /*auto-expand width for horizontal scrolling: boolean*/ 29 autoScrollOnFocus:true /*auto-scroll on focused elements: boolean*/ 30 }, 31 callbacks:{ 32 onScrollStart:function(){}, /*user custom callback function on scroll start event*/ 33 onScroll:function(){}, /*user custom callback function on scroll event*/ 34 onTotalScroll:function(){}, /*user custom callback function on scroll end reached event*/ 35 onTotalScrollBack:function(){}, /*user custom callback function on scroll begin reached event*/ 36 onTotalScrollOffset:0, /*scroll end reached offset: integer (pixels)*/ 37 whileScrolling:false, /*user custom callback function on scrolling event*/ 38 whileScrollingInterval:30 /*interval for calling whileScrolling callback: integer (milliseconds)*/ 39 } 40 }, 41 options=$.extend(true,defaults,options); 42 /*check for touch device*/ 43 $(document).data("mCS-is-touch-device",false); 44 if(is_touch_device()){ 45 $(document).data("mCS-is-touch-device",true); 46 } 47 function is_touch_device(){ 48 return !!("ontouchstart" in window) ? 1 : 0; 49 } 50 return this.each(function(){ 51 var $this=$(this); 52 /*set element width/height, create markup for custom scrollbars, add classes*/ 53 if(options.set_width){ 54 $this.css("width",options.set_width); 55 } 56 if(options.set_height){ 57 $this.css("height",options.set_height); 58 } 59 if(!$(document).data("mCustomScrollbar-index")){ 60 $(document).data("mCustomScrollbar-index","1"); 61 }else{ 62 var mCustomScrollbarIndex=parseInt($(document).data("mCustomScrollbar-index")); 63 $(document).data("mCustomScrollbar-index",mCustomScrollbarIndex+1); 64 } 65 $this.wrapInner("<div class='mCustomScrollBox' id='mCSB_"+$(document).data("mCustomScrollbar-index")+"' style='position:relative; height:100%; overflow:hidden; max-width:100%;' />").addClass("mCustomScrollbar _mCS_"+$(document).data("mCustomScrollbar-index")); 66 var mCustomScrollBox=$this.children(".mCustomScrollBox"); 67 if(options.horizontalScroll){ 68 mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />"); 69 var mCSB_h_wrapper=mCustomScrollBox.children(".mCSB_h_wrapper"); 70 mCSB_h_wrapper.wrapInner("<div class='mCSB_container' style='position:absolute; left:0;' />").children(".mCSB_container").css({"width":mCSB_h_wrapper.children().outerWidth(),"position":"relative"}).unwrap(); 71 }else{ 72 mCustomScrollBox.wrapInner("<div class='mCSB_container' style='position:relative; top:0;' />"); 73 } 74 var mCSB_container=mCustomScrollBox.children(".mCSB_container"); 75 if($(document).data("mCS-is-touch-device")){ 76 mCSB_container.addClass("mCS_touch"); 77 } 78 mCSB_container.after("<div class='mCSB_scrollTools' style='position:absolute;'><div class='mCSB_draggerContainer' style='position:relative;'><div class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' style='position:relative;'></div></div><div class='mCSB_draggerRail'></div></div></div>"); 79 var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), 80 mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), 81 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); 82 if(options.horizontalScroll){ 83 mCSB_dragger.data("minDraggerWidth",mCSB_dragger.width()); 84 }else{ 85 mCSB_dragger.data("minDraggerHeight",mCSB_dragger.height()); 86 } 87 if(options.scrollButtons.enable){ 88 if(options.horizontalScroll){
89 mCSB_scrollTools.prepend("<a class='mCSB_buttonLeft' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonRight' style='display:block; position:relative;'></a>"); 90 }else{ 91 mCSB_scrollTools.prepend("<a class='mCSB_buttonUp' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonDown' style='display:block; position:relative;'></a>"); 92 } 93 } 94 /*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/ 95 mCustomScrollBox.bind("scroll",function(){ 96 if(!$this.is(".mCS_disabled")){ /*native focus scrolling for disabled scrollbars*/ 97 mCustomScrollBox.scrollTop(0).scrollLeft(0); 98 } 99 }); 100 /*store options, global vars/states, intervals and update element*/ 101 $this.data({ 102 /*init state*/ 103 "mCS_Init":true, 104 /*option parameters*/ 105 "horizontalScroll":options.horizontalScroll, 106 "scrollInertia":options.scrollInertia, 107 "scrollEasing":options.scrollEasing, 108 "mouseWheel":options.mouseWheel, 109 "mouseWheelPixels":options.mouseWheelPixels, 110 "autoDraggerLength":options.autoDraggerLength, 111 "scrollButtons_enable":options.scrollButtons.enable, 112 "scrollButtons_scrollType":options.scrollButtons.scrollType, 113 "scrollButtons_scrollSpeed":options.scrollButtons.scrollSpeed, 114 "scrollButtons_scrollAmount":options.scrollButtons.scrollAmount, 115 "autoExpandHorizontalScroll":options.advanced.autoExpandHorizontalScroll, 116 "autoScrollOnFocus":options.advanced.autoScrollOnFocus, 117 "onScrollStart_Callback":options.callbacks.onScrollStart, 118 "onScroll_Callback":options.callbacks.onScroll, 119 "onTotalScroll_Callback":options.callbacks.onTotalScroll, 120 "onTotalScrollBack_Callback":options.callbacks.onTotalScrollBack, 121 "onTotalScroll_Offset":options.callbacks.onTotalScrollOffset, 122 "whileScrolling_Callback":options.callbacks.whileScrolling, 123 "whileScrolling_Interval":options.callbacks.whileScrollingInterval, 124 /*events binding state*/ 125 "bindEvent_scrollbar_click":false, 126 "bindEvent_mousewheel":false, 127 "bindEvent_focusin":false, 128 "bindEvent_buttonsContinuous_y":false, 129 "bindEvent_buttonsContinuous_x":false, 130 "bindEvent_buttonsPixels_y":false, 131 "bindEvent_buttonsPixels_x":false, 132 "bindEvent_scrollbar_touch":false, 133 "bindEvent_content_touch":false, 134 /*buttons intervals*/ 135 "mCSB_buttonScrollRight":false, 136 "mCSB_buttonScrollLeft":false, 137 "mCSB_buttonScrollDown":false, 138 "mCSB_buttonScrollUp":false, 139 /*callback intervals*/ 140 "whileScrolling":false 141 }).mCustomScrollbar("update"); 142 /*detect max-width*/ 143 if(options.horizontalScroll){ 144 if($this.css("max-width")!=="none"){ 145 if(!options.advanced.updateOnContentResize){ /*needs updateOnContentResize*/ 146 options.advanced.updateOnContentResize=true; 147 } 148 $this.data({"mCS_maxWidth":parseInt($this.css("max-width")),"mCS_maxWidth_Interval":setInterval(function(){ 149 if(mCSB_container.outerWidth()>$this.data("mCS_maxWidth")){ 150 clearInterval($this.data("mCS_maxWidth_Interval")); 151 $this.mCustomScrollbar("update"); 152 } 153 },150)}); 154 } 155 }else{ 156 /*detect max-height*/ 157 if($this.css("max-height")!=="none"){ 158 $this.data({"mCS_maxHeight":parseInt($this.css("max-height")),"mCS_maxHeight_Interval":setInterval(function(){ 159 mCustomScrollBox.css("max-height",$this.data("mCS_maxHeight")); 160 if(mCSB_container.outerHeight()>$this.data("mCS_maxHeight")){ 161 clearInterval($this.data("mCS_maxHeight_Interval")); 162 $this.mCustomScrollbar("update"); 163 } 164 },150)}); 165 } 166 } 167 /*window resize fn (for layouts based on percentages)*/ 168 if(options.advanced.updateOnBrowserResize){ 169 var mCSB_resizeTimeout; 170 $(window).resize(function(){ 171 if(mCSB_resizeTimeout){ 172 clearTimeout(mCSB_resizeTimeout); 173 } 174 mCSB_resizeTimeout=setTimeout(function(){ 175 if(!$this.is(".mCS_disabled") && !$this.is(".mCS_destroyed")){ 176 $this.mCustomScrollbar("update"); 177 } 178 },150); 179 });
180 } 181 /*content resize fn (for dynamically generated content)*/ 182 if(options.advanced.updateOnContentResize){ 183 var mCSB_onContentResize; 184 if(options.horizontalScroll){ 185 var mCSB_containerOldSize=mCSB_container.outerWidth(); 186 }else{ 187 var mCSB_containerOldSize=mCSB_container.outerHeight(); 188 } 189 mCSB_onContentResize=setInterval(function(){ 190 if(options.horizontalScroll){ 191 if(options.advanced.autoExpandHorizontalScroll){ 192 mCSB_container.css({"position":"absolute","width":"auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap(); 193 } 194 var mCSB_containerNewSize=mCSB_container.outerWidth(); 195 }else{ 196 var mCSB_containerNewSize=mCSB_container.outerHeight(); 197 } 198 if(mCSB_containerNewSize!=mCSB_containerOldSize){ 199 $this.mCustomScrollbar("update"); 200 mCSB_containerOldSize=mCSB_containerNewSize; 201 } 202 },300); 203 } 204 }); 205 }, 206 update:function(){ 207 var $this=$(this), 208 mCustomScrollBox=$this.children(".mCustomScrollBox"), 209 mCSB_container=mCustomScrollBox.children(".mCSB_container"); 210 mCSB_container.removeClass("mCS_no_scrollbar"); 211 $this.removeClass("mCS_disabled mCS_destroyed"); 212 mCustomScrollBox.scrollTop(0).scrollLeft(0); /*reset scrollTop/scrollLeft to prevent browser focus scrolling*/ 213 var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), 214 mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), 215 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); 216 if($this.data("horizontalScroll")){ 217 var mCSB_buttonLeft=mCSB_scrollTools.children(".mCSB_buttonLeft"), 218 mCSB_buttonRight=mCSB_scrollTools.children(".mCSB_buttonRight"), 219 mCustomScrollBoxW=mCustomScrollBox.width(); 220 if($this.data("autoExpandHorizontalScroll")){ 221 mCSB_container.css({"position":"absolute","width":"auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap(); 222 } 223 var mCSB_containerW=mCSB_container.outerWidth(); 224 }else{ 225 var mCSB_buttonUp=mCSB_scrollTools.children(".mCSB_buttonUp"), 226 mCSB_buttonDown=mCSB_scrollTools.children(".mCSB_buttonDown"), 227 mCustomScrollBoxH=mCustomScrollBox.height(), 228 mCSB_containerH=mCSB_container.outerHeight(); 229 } 230 if(mCSB_containerH>mCustomScrollBoxH && !$this.data("horizontalScroll")){ /*content needs vertical scrolling*/ 231 mCSB_scrollTools.css("display","block"); 232 var mCSB_draggerContainerH=mCSB_draggerContainer.height(); 233 /*auto adjust scrollbar dragger length analogous to content*/ 234 if($this.data("autoDraggerLength")){ 235 var draggerH=Math.round(mCustomScrollBoxH/mCSB_containerH*mCSB_draggerContainerH), 236 minDraggerH=mCSB_dragger.data("minDraggerHeight"); 237 if(draggerH<=minDraggerH){ /*min dragger height*/ 238 mCSB_dragger.css({"height":minDraggerH}); 239 }else if(draggerH>=mCSB_draggerContainerH-10){ /*max dragger height*/ 240 var mCSB_draggerContainerMaxH=mCSB_draggerContainerH-10; 241 mCSB_dragger.css({"height":mCSB_draggerContainerMaxH}); 242 }else{ 243 mCSB_dragger.css({"height":draggerH}); 244 } 245 mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height":mCSB_dragger.height()+"px"}); 246 } 247 var mCSB_draggerH=mCSB_dragger.height(), 248 /*calculate and store scroll amount, add scrolling*/ 249 scrollAmount=(mCSB_containerH-mCustomScrollBoxH)/(mCSB_draggerContainerH-mCSB_draggerH); 250 $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); 251 /*scroll*/ 252 var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().top)); 253 $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false}); 254 }else if(mCSB_containerW>mCustomScrollBoxW && $this.data("horizontalScroll")){ /*content needs horizontal scrolling*/ 255 mCSB_scrollTools.css("display","block"); 256 var mCSB_draggerContainerW=mCSB_draggerContainer.width(); 257 /*auto adjust scrollbar dragger length analogous to content*/ 258 if($this.data("autoDraggerLength")){ 259 var draggerW=Math.round(mCustomScrollBoxW/mCSB_containerW*mCSB_draggerContainerW), 260 minDraggerW=mCSB_dragger.data("minDraggerWidth"); 261 if(draggerW<=minDraggerW){ /*min dragger height*/ 262 mCSB_dragger.css({"width":minDraggerW}); 263 }else if(draggerW>=mCSB_draggerContainerW-10){ /*max dragger height*/ 264 var mCSB_draggerContainerMaxW=mCSB_draggerContainerW-10; 265 mCSB_dragger.css({"width":mCSB_draggerContainerMaxW}); 266 }else{ 267 mCSB_dragger.css({"width":draggerW}); 268 } 269 } 270 var mCSB_draggerW=mCSB_dragger.width(), 271 /*calculate and store scroll amount, add scrolling*/ 272 scrollAmount=(mCSB_containerW-mCustomScrollBoxW)/(mCSB_draggerContainerW-mCSB_draggerW); 273 $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); 274 /*scroll*/ 275 var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().left)); 276 $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false}); 277 }else{ /*content does not need scrolling*/ 278 /*unbind events, reset content position, hide scrollbars, remove classes*/ 279 mCustomScrollBox.unbind("mousewheel focusin"); 280 if($this.data("horizontalScroll")){ 281 mCSB_dragger.add(mCSB_container).css("left",0); 282 }else{ 283 mCSB_dragger.add(mCSB_container).css("top",0); 284 } 285 mCSB_scrollTools.css("display","none"); 286 mCSB_container.addClass("mCS_no_scrollbar"); 287 $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false}); 288 } 289 }, 290 scrolling:function(mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight){ 291 var $this=$(this); 292 /*while scrolling callback*/ 293 $this.mCustomScrollbar("callbacks","whileScrolling"); 294 /*drag scrolling*/ 295 if(!mCSB_dragger.hasClass("ui-draggable")){ /*apply drag function once*/ 296 if($this.data("horizontalScroll")){ 297 var draggableAxis="x"; 298 }else{ 299 var draggableAxis="y"; 300 } 301 mCSB_dragger.draggable({ 302 axis:draggableAxis, 303 containment:"parent", 304 drag:function(event,ui){ 305 $this.mCustomScrollbar("scroll"); 306 mCSB_dragger.addClass("mCSB_dragger_onDrag"); 307 }, 308 stop:function(event,ui){ 309 mCSB_dragger.removeClass("mCSB_dragger_onDrag"); 310 } 311 }); 312 } 313 if(!$this.data("bindEvent_scrollbar_click")){ /*bind once*/ 314 mCSB_draggerContainer.bind("click",function(e){
315 if($this.data("horizontalScroll")){ 316 var mouseCoord=(e.pageX-mCSB_draggerContainer.offset().left); 317 if(mouseCoord<mCSB_dragger.position().left || mouseCoord>(mCSB_dragger.position().left+mCSB_dragger.width())){ 318 var scrollToPos=mouseCoord; 319 if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 320 scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width(); 321 } 322 mCSB_dragger.css("left",scrollToPos); 323 $this.mCustomScrollbar("scroll"); 324 } 325 }else{ 326 var mouseCoord=(e.pageY-mCSB_draggerContainer.offset().top); 327 if(mouseCoord<mCSB_dragger.position().top || mouseCoord>(mCSB_dragger.position().top+mCSB_dragger.height())){ 328 var scrollToPos=mouseCoord; 329 if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 330 scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height(); 331 } 332 mCSB_dragger.css("top",scrollToPos); 333 $this.mCustomScrollbar("scroll"); 334 } 335 } 336 }); 337 $this.data({"bindEvent_scrollbar_click":true}); 338 } 339 /*mousewheel scrolling*/ 340 if($this.data("mouseWheel")){ 341 var mousewheelVel=$this.data("mouseWheel"); 342 if($this.data("mouseWheel")==="auto"){ 343 mousewheelVel=8; /*default mousewheel velocity*/ 344 /*check for safari browser on mac osx to lower mousewheel velocity*/ 345 var os=navigator.userAgent; 346 if(os.indexOf("Mac")!=-1 && os.indexOf("Safari")!=-1 && os.indexOf("AppleWebKit")!=-1 && os.indexOf("Chrome")==-1){ 347 mousewheelVel=1; 348 } 349 } 350 if(!$this.data("bindEvent_mousewheel")){ /*bind once*/ 351 mCustomScrollBox.bind("mousewheel",function(event,delta){ 352 event.preventDefault(); 353 var vel=Math.abs(delta*mousewheelVel); 354 if($this.data("horizontalScroll")){ 355 if($this.data("mouseWheel")==="pixels"){ 356 if(delta<0){ 357 delta=-1; 358 }else{ 359 delta=1; 360 } 361 var scrollTo=Math.abs(Math.round(mCSB_container.position().left))-(delta*$this.data("mouseWheelPixels")); 362 $this.mCustomScrollbar("scrollTo",scrollTo); 363 }else{ 364 var posX=mCSB_dragger.position().left-(delta*vel); 365 mCSB_dragger.css("left",posX); 366 if(mCSB_dragger.position().left<0){ 367 mCSB_dragger.css("left",0); 368 } 369 var mCSB_draggerContainerW=mCSB_draggerContainer.width(), 370 mCSB_draggerW=mCSB_dragger.width(); 371 if(mCSB_dragger.position().left>mCSB_draggerContainerW-mCSB_draggerW){ 372 mCSB_dragger.css("left",mCSB_draggerContainerW-mCSB_draggerW); 373 } 374 $this.mCustomScrollbar("scroll"); 375 } 376 }else{ 377 if($this.data("mouseWheel")==="pixels"){ 378 if(delta<0){ 379 delta=-1; 380 }else{ 381 delta=1; 382 } 383 var scrollTo=Math.abs(Math.round(mCSB_container.position().top))-(delta*$this.data("mouseWheelPixels")); 384 $this.mCustomScrollbar("scrollTo",scrollTo); 385 }else{ 386 var posY=mCSB_dragger.position().top-(delta*vel); 387 mCSB_dragger.css("top",posY); 388 if(mCSB_dragger.position().top<0){ 389 mCSB_dragger.css("top",0); 390 } 391 var mCSB_draggerContainerH=mCSB_draggerContainer.height(), 392 mCSB_draggerH=mCSB_dragger.height(); 393 if(mCSB_dragger.position().top>mCSB_draggerContainerH-mCSB_draggerH){ 394 mCSB_dragger.css("top",mCSB_draggerContainerH-mCSB_draggerH); 395 } 396 $this.mCustomScrollbar("scroll"); 397 } 398 } 399 }); 400 $this.data({"bindEvent_mousewheel":true}); 401 } 402 } 403 /*buttons scrolling*/ 404 if($this.data("scrollButtons_enable")){ 405 if($this.data("scrollButtons_scrollType")==="pixels"){ /*scroll by pixels*/ 406 var pixelsScrollTo; 407 if($.browser.msie && parseInt($.browser.version)<9){ /*stupid ie8*/ 408 $this.data("scrollInertia",0); 409 } 410 if($this.data("horizontalScroll")){ 411 mCSB_buttonRight.add(mCSB_buttonLeft).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); 412 $this.data({"bindEvent_buttonsContinuous_x":false}); 413 if(!$this.data("bindEvent_buttonsPixels_x")){ /*bind once*/ 414 /*scroll right*/ 415 mCSB_buttonRight.bind("click",function(e){
416 e.preventDefault(); 417 if(!mCSB_container.is(":animated")){ 418 pixelsScrollTo=Math.abs(mCSB_container.position().left)+$this.data("scrollButtons_scrollAmount"); 419 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 420 } 421 }); 422 /*scroll left*/ 423 mCSB_buttonLeft.bind("click",function(e){ 424 e.preventDefault(); 425 if(!mCSB_container.is(":animated")){ 426 pixelsScrollTo=Math.abs(mCSB_container.position().left)-$this.data("scrollButtons_scrollAmount"); 427 if(mCSB_container.position().left>=-$this.data("scrollButtons_scrollAmount")){ 428 pixelsScrollTo="left"; 429 } 430 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 431 } 432 }); 433 $this.data({"bindEvent_buttonsPixels_x":true}); 434 } 435 }else{ 436 mCSB_buttonDown.add(mCSB_buttonUp).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); 437 $this.data({"bindEvent_buttonsContinuous_y":false}); 438 if(!$this.data("bindEvent_buttonsPixels_y")){ /*bind once*/ 439 /*scroll down*/ 440 mCSB_buttonDown.bind("click",function(e){ 441 e.preventDefault(); 442 if(!mCSB_container.is(":animated")){ 443 pixelsScrollTo=Math.abs(mCSB_container.position().top)+$this.data("scrollButtons_scrollAmount"); 444 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 445 } 446 }); 447 /*scroll up*/ 448 mCSB_buttonUp.bind("click",function(e){ 449 e.preventDefault(); 450 if(!mCSB_container.is(":animated")){ 451 pixelsScrollTo=Math.abs(mCSB_container.position().top)-$this.data("scrollButtons_scrollAmount"); 452 if(mCSB_container.position().top>=-$this.data("scrollButtons_scrollAmount")){ 453 pixelsScrollTo="top"; 454 } 455 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 456 } 457 }); 458 $this.data({"bindEvent_buttonsPixels_y":true}); 459 } 460 } 461 }else{ /*continuous scrolling*/ 462 if($this.data("horizontalScroll")){ 463 mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click"); 464 $this.data({"bindEvent_buttonsPixels_x":false}); 465 if(!$this.data("bindEvent_buttonsContinuous_x")){ /*bind once*/ 466 /*scroll right*/ 467 mCSB_buttonRight.bind("mousedown touchstart onmsgesturestart",function(e){ 468 e.preventDefault(); 469 e.stopPropagation(); 470 $this.data({"mCSB_buttonScrollRight":setInterval(function(){ 471 var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().left))+$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount")); 472 $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true}); 473 },30)}); 474 }); 475 var mCSB_buttonRight_stop=function(e){ 476 e.preventDefault(); 477 e.stopPropagation(); 478 clearInterval($this.data("mCSB_buttonScrollRight")); 479 } 480 mCSB_buttonRight.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonRight_stop); 481 /*scroll left*/ 482 mCSB_buttonLeft.bind("mousedown touchstart onmsgesturestart",function(e){ 483 e.preventDefault(); 484 e.stopPropagation(); 485 $this.data({"mCSB_buttonScrollLeft":setInterval(function(){ 486 var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().left))-$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount")); 487 $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true}); 488 },30)}); 489 }); 490 var mCSB_buttonLeft_stop=function(e){ 491 e.preventDefault(); 492 e.stopPropagation(); 493 clearInterval($this.data("mCSB_buttonScrollLeft")); 494 } 495 mCSB_buttonLeft.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonLeft_stop); 496 $this.data({"bindEvent_buttonsContinuous_x":true}); 497 } 498 }else{ 499 mCSB_buttonDown.add(mCSB_buttonUp).unbind("click"); 500 $this.data({"bindEvent_buttonsPixels_y":false}); 501 if(!$this.data("bindEvent_buttonsContinuous_y")){ /*bind once*/ 502 /*scroll down*/ 503 mCSB_buttonDown.bind("mousedown touchstart onmsgesturestart",function(e){
504 e.preventDefault(); 505 e.stopPropagation(); 506 $this.data({"mCSB_buttonScrollDown":setInterval(function(){ 507 var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().top))+$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount")); 508 $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true}); 509 },30)}); 510 }); 511 var mCSB_buttonDown_stop=function(e){ 512 e.preventDefault(); 513 e.stopPropagation(); 514 clearInterval($this.data("mCSB_buttonScrollDown")); 515 } 516 mCSB_buttonDown.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonDown_stop); 517 /*scroll up*/ 518 mCSB_buttonUp.bind("mousedown touchstart onmsgesturestart",function(e){ 519 e.preventDefault(); 520 e.stopPropagation(); 521 $this.data({"mCSB_buttonScrollUp":setInterval(function(){ 522 var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().top))-$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount")); 523 $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true}); 524 },30)}); 525 }); 526 var mCSB_buttonUp_stop=function(e){ 527 e.preventDefault(); 528 e.stopPropagation(); 529 clearInterval($this.data("mCSB_buttonScrollUp")); 530 } 531 mCSB_buttonUp.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonUp_stop); 532 $this.data({"bindEvent_buttonsContinuous_y":true}); 533 } 534 } 535 } 536 } 537 /*scrolling on element focus (e.g. via TAB key)*/ 538 if($this.data("autoScrollOnFocus")){ 539 if(!$this.data("bindEvent_focusin")){ /*bind once*/ 540 mCustomScrollBox.bind("focusin",function(){ 541 mCustomScrollBox.scrollTop(0).scrollLeft(0); 542 var focusedElem=$(document.activeElement); 543 if(focusedElem.is("input,textarea,select,button,a[tabindex],area,object")){ 544 if($this.data("horizontalScroll")){ 545 var mCSB_containerX=mCSB_container.position().left, 546 focusedElemX=focusedElem.position().left, 547 mCustomScrollBoxW=mCustomScrollBox.width(), 548 focusedElemW=focusedElem.outerWidth(); 549 if(mCSB_containerX+focusedElemX>=0 && mCSB_containerX+focusedElemX<=mCustomScrollBoxW-focusedElemW){ 550 /*just focus...*/ 551 }else{ /*scroll, then focus*/ 552 var moveDragger=focusedElemX/$this.data("scrollAmount"); 553 if(moveDragger>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 554 moveDragger=mCSB_draggerContainer.width()-mCSB_dragger.width(); 555 } 556 mCSB_dragger.css("left",moveDragger); 557 $this.mCustomScrollbar("scroll"); 558 } 559 }else{ 560 var mCSB_containerY=mCSB_container.position().top, 561 focusedElemY=focusedElem.position().top, 562 mCustomScrollBoxH=mCustomScrollBox.height(), 563 focusedElemH=focusedElem.outerHeight(); 564 if(mCSB_containerY+focusedElemY>=0 && mCSB_containerY+focusedElemY<=mCustomScrollBoxH-focusedElemH){ 565 /*just focus...*/ 566 }else{ /*scroll, then focus*/ 567 var moveDragger=focusedElemY/$this.data("scrollAmount"); 568 if(moveDragger>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 569 moveDragger=mCSB_draggerContainer.height()-mCSB_dragger.height(); 570 } 571 mCSB_dragger.css("top",moveDragger); 572 $this.mCustomScrollbar("scroll"); 573 } 574 } 575 } 576 }); 577 $this.data({"bindEvent_focusin":true}); 578 } 579 } 580 /*touch events*/ 581 if($(document).data("mCS-is-touch-device")){ 582 /*scrollbar touch-drag*/ 583 if(!$this.data("bindEvent_scrollbar_touch")){ /*bind once*/ 584 var mCSB_draggerTouchY, 585 mCSB_draggerTouchX; 586 mCSB_dragger.bind("touchstart onmsgesturestart",function(e){ 587 e.preventDefault(); 588 e.stopPropagation(); 589 var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], 590 elem=$(this), 591 elemOffset=elem.offset(), 592 x=touch.pageX-elemOffset.left, 593 y=touch.pageY-elemOffset.top; 594 if(x<elem.width() && x>0 && y<elem.height() && y>0){ 595 mCSB_draggerTouchY=y; 596 mCSB_draggerTouchX=x; 597 } 598 });
599 mCSB_dragger.bind("touchmove onmsgesturechange",function(e){ 600 e.preventDefault(); 601 e.stopPropagation(); 602 var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], 603 elem=$(this), 604 elemOffset=elem.offset(), 605 x=touch.pageX-elemOffset.left, 606 y=touch.pageY-elemOffset.top; 607 if($this.data("horizontalScroll")){ 608 $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().left-(mCSB_draggerTouchX))+x,{moveDragger:true}); 609 }else{ 610 $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().top-(mCSB_draggerTouchY))+y,{moveDragger:true}); 611 } 612 }); 613 $this.data({"bindEvent_scrollbar_touch":true}); 614 } 615 /*content touch-drag*/ 616 if(!$this.data("bindEvent_content_touch")){ /*bind once*/ 617 var touch, 618 elem, 619 elemOffset, 620 x, 621 y, 622 mCSB_containerTouchY, 623 mCSB_containerTouchX; 624 mCSB_container.bind("touchstart onmsgesturestart",function(e){ 625 touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 626 elem=$(this); 627 elemOffset=elem.offset(); 628 x=touch.pageX-elemOffset.left; 629 y=touch.pageY-elemOffset.top; 630 mCSB_containerTouchY=y; 631 mCSB_containerTouchX=x; 632 }); 633 mCSB_container.bind("touchmove onmsgesturechange",function(e){ 634 e.preventDefault(); 635 e.stopPropagation(); 636 touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 637 elem=$(this).parent(); 638 elemOffset=elem.offset(); 639 x=touch.pageX-elemOffset.left; 640 y=touch.pageY-elemOffset.top; 641 if($this.data("horizontalScroll")){ 642 $this.mCustomScrollbar("scrollTo",mCSB_containerTouchX-x); 643 }else{ 644 $this.mCustomScrollbar("scrollTo",mCSB_containerTouchY-y); 645 } 646 }); 647 $this.data({"bindEvent_content_touch":true}); 648 } 649 } 650 }, 651 scroll:function(bypassCallbacks){ 652 var $this=$(this), 653 mCSB_dragger=$this.find(".mCSB_dragger"), 654 mCSB_container=$this.find(".mCSB_container"), 655 mCustomScrollBox=$this.find(".mCustomScrollBox"); 656 if($this.data("horizontalScroll")){ 657 var draggerX=mCSB_dragger.position().left, 658 targX=-draggerX*$this.data("scrollAmount"), 659 thisX=mCSB_container.position().left, 660 posX=Math.round(thisX-targX); 661 }else{ 662 var draggerY=mCSB_dragger.position().top, 663 targY=-draggerY*$this.data("scrollAmount"), 664 thisY=mCSB_container.position().top, 665 posY=Math.round(thisY-targY); 666 } 667 if($.browser.webkit){ /*fix webkit zoom and jquery animate*/ 668 var screenCssPixelRatio=(window.outerWidth-8)/window.innerWidth, 669 isZoomed=(screenCssPixelRatio<.98 || screenCssPixelRatio>1.02); 670 } 671 if($this.data("scrollInertia")===0 || isZoomed){ 672 if(!bypassCallbacks){ 673 $this.mCustomScrollbar("callbacks","onScrollStart"); /*user custom callback functions*/ 674 } 675 if($this.data("horizontalScroll")){ 676 mCSB_container.css("left",targX); 677 }else{ 678 mCSB_container.css("top",targY); 679 } 680 if(!bypassCallbacks){ 681 /*user custom callback functions*/ 682 if($this.data("whileScrolling")){ 683 $this.data("whileScrolling_Callback").call(); 684 } 685 $this.mCustomScrollbar("callbacks","onScroll"); 686 } 687 $this.data({"mCS_Init":false}); 688 }else{ 689 if(!bypassCallbacks){ 690 $this.mCustomScrollbar("callbacks","onScrollStart"); /*user custom callback functions*/ 691 } 692 if($this.data("horizontalScroll")){ 693 mCSB_container.stop().animate({left:"-="+posX},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 694 if(!bypassCallbacks){ 695 $this.mCustomScrollbar("callbacks","onScroll"); /*user custom callback functions*/ 696 } 697 $this.data({"mCS_Init":false}); 698 }); 699 }else{ 700 mCSB_container.stop().animate({top:"-="+posY},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 701 if(!bypassCallbacks){ 702 $this.mCustomScrollbar("callbacks","onScroll"); /*user custom callback functions*/ 703 } 704 $this.data({"mCS_Init":false}); 705 });
706 } 707 } 708 }, 709 scrollTo:function(scrollTo,options){ 710 var defaults={ 711 moveDragger:false, 712 callback:true 713 }, 714 options=$.extend(defaults,options), 715 $this=$(this), 716 scrollToPos, 717 mCustomScrollBox=$this.find(".mCustomScrollBox"), 718 mCSB_container=mCustomScrollBox.children(".mCSB_container"), 719 mCSB_draggerContainer=$this.find(".mCSB_draggerContainer"), 720 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"), 721 targetPos; 722 if(scrollTo || scrollTo===0){ 723 if(typeof(scrollTo)==="number"){ /*if integer, scroll by number of pixels*/ 724 if(options.moveDragger){ /*scroll dragger*/ 725 scrollToPos=scrollTo; 726 }else{ /*scroll content by default*/ 727 targetPos=scrollTo; 728 scrollToPos=Math.round(targetPos/$this.data("scrollAmount")); 729 } 730 }else if(typeof(scrollTo)==="string"){ /*if string, scroll by element position*/ 731 var target; 732 if(scrollTo==="top"){ /*scroll to top*/ 733 target=0; 734 }else if(scrollTo==="bottom" && !$this.data("horizontalScroll")){ /*scroll to bottom*/ 735 target=mCSB_container.outerHeight()-mCustomScrollBox.height(); 736 }else if(scrollTo==="left"){ /*scroll to left*/ 737 target=0; 738 }else if(scrollTo==="right" && $this.data("horizontalScroll")){ /*scroll to right*/ 739 target=mCSB_container.outerWidth()-mCustomScrollBox.width(); 740 }else if(scrollTo==="first"){ /*scroll to first element position*/ 741 target=$this.find(".mCSB_container").find(":first"); 742 }else if(scrollTo==="last"){ /*scroll to last element position*/ 743 target=$this.find(".mCSB_container").find(":last"); 744 }else{ /*scroll to element position*/ 745 target=$this.find(scrollTo); 746 } 747 if(target.length===1){ /*if such unique element exists, scroll to it*/ 748 if($this.data("horizontalScroll")){ 749 targetPos=target.position().left; 750 }else{ 751 targetPos=target.position().top; 752 } 753 scrollToPos=Math.ceil(targetPos/$this.data("scrollAmount")); 754 }else{ 755 scrollToPos=target; 756 } 757 } 758 /*scroll to*/ 759 if(scrollToPos<0){ 760 scrollToPos=0; 761 } 762 if($this.data("horizontalScroll")){ 763 if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 764 scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width(); 765 } 766 mCSB_dragger.css("left",scrollToPos); 767 }else{ 768 if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 769 scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height(); 770 } 771 mCSB_dragger.css("top",scrollToPos); 772 } 773 if(options.callback){ 774 $this.mCustomScrollbar("scroll",false); 775 }else{ 776 $this.mCustomScrollbar("scroll",true); 777 } 778 } 779 }, 780 callbacks:function(callback){ 781 var $this=$(this), 782 mCustomScrollBox=$this.find(".mCustomScrollBox"), 783 mCSB_container=$this.find(".mCSB_container"); 784 switch(callback){ 785 /*start scrolling callback*/ 786 case "onScrollStart": 787 if(!mCSB_container.is(":animated")){ 788 $this.data("onScrollStart_Callback").call(); 789 } 790 break; 791 /*end scrolling callback*/ 792 case "onScroll": 793 if($this.data("horizontalScroll")){ 794 var mCSB_containerX=Math.round(mCSB_container.position().left); 795 if(mCSB_containerX<0 && mCSB_containerX<=mCustomScrollBox.width()-mCSB_container.outerWidth()+$this.data("onTotalScroll_Offset")){ 796 $this.data("onTotalScroll_Callback").call(); 797 }else if(mCSB_containerX>=-$this.data("onTotalScroll_Offset")){ 798 $this.data("onTotalScrollBack_Callback").call(); 799 }else{ 800 $this.data("onScroll_Callback").call(); 801 } 802 }else{ 803 var mCSB_containerY=Math.round(mCSB_container.position().top); 804 if(mCSB_containerY<0 && mCSB_containerY<=mCustomScrollBox.height()-mCSB_container.outerHeight()+$this.data("onTotalScroll_Offset")){ 805 $this.data("onTotalScroll_Callback").call(); 806 }else if(mCSB_containerY>=-$this.data("onTotalScroll_Offset")){ 807 $this.data("onTotalScrollBack_Callback").call(); 808 }else{ 809 $this.data("onScroll_Callback").call(); 810 } 811 } 812 break; 813 /*while scrolling callback*/ 814 case "whileScrolling": 815 if($this.data("whileScrolling_Callback") && !$this.data("whileScrolling")){ 816 $this.data({"whileScrolling":setInterval(function(){ 817 if(mCSB_container.is(":animated") && !$this.data("mCS_Init")){ 818 $this.data("whileScrolling_Callback").call(); 819 } 820 },$this.data("whileScrolling_Interval"))}); 821 } 822 break; 823 } 824 }, 825 disable:function(resetScroll){ 826 var $this=$(this), 827 mCustomScrollBox=$this.children(".mCustomScrollBox"), 828 mCSB_container=mCustomScrollBox.children(".mCSB_container"), 829 mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), 830 mCSB_dragger=mCSB_scrollTools.find(".mCSB_dragger"); 831 mCustomScrollBox.unbind("mousewheel focusin"); 832 if(resetScroll){ 833 if($this.data("horizontalScroll")){ 834 mCSB_dragger.add(mCSB_container).css("left",0); 835 }else{ 836 mCSB_dragger.add(mCSB_container).css("top",0); 837 } 838 } 839 mCSB_scrollTools.css("display","none"); 840 mCSB_container.addClass("mCS_no_scrollbar"); 841 $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false}).addClass("mCS_disabled"); 842 }, 843 destroy:function(){ 844 var $this=$(this), 845 content=$this.find(".mCSB_container").html(); 846 $this.find(".mCustomScrollBox").remove(); 847 $this.html(content).removeClass("mCustomScrollbar _mCS_"+$(document).data("mCustomScrollbar-index")).addClass("mCS_destroyed"); 848 } 849 }
850 $.fn.mCustomScrollbar=function(method){ 851 if(methods[method]){ 852 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 853 }else if(typeof method==="object" || !method){ 854 return methods.init.apply(this,arguments); 855 }else{ 856 $.error("Method "+method+" does not exist"); 857 } 858 }; 859})(jQuery); 860/*iOS 6 bug fix 861 iOS 6 suffers from a bug that kills timers that are created while a page is scrolling. 862 The following fixes that problem by recreating timers after scrolling finishes (with interval correction).*/ 863var iOSVersion=iOSVersion(); 864if(iOSVersion>=6){ 865 (function(h){var a={};var d={};var e=h.setTimeout;var f=h.setInterval;var i=h.clearTimeout;var c=h.clearInterval;if(!h.addEventListener){return false}function j(q,n,l){var p,k=l[0],m=(q===f);function o(){if(k){k.apply(h,arguments);if(!m){delete n[p];k=null}}}l[0]=o;p=q.apply(h,l);n[p]={args:l,created:Date.now(),cb:k,id:p};return p}function b(q,o,k,r,t){var l=k[r];if(!l){return}var m=(q===f);o(l.id);if(!m){var n=l.args[1];var p=Date.now()-l.created;if(p<0){p=0}n-=p;if(n<0){n=0}l.args[1]=n}function s(){if(l.cb){l.cb.apply(h,arguments);if(!m){delete k[r];l.cb=null}}}l.args[0]=s;l.created=Date.now();l.id=q.apply(h,l.args)}h.setTimeout=function(){return j(e,a,arguments)};h.setInterval=function(){return j(f,d,arguments)};h.clearTimeout=function(l){var k=a[l];if(k){delete a[l];i(k.id)}};h.clearInterval=function(l){var k=d[l];if(k){delete d[l];c(k.id)}};var g=h;while(g.location!=g.parent.location){g=g.parent}g.addEventListener("scroll",function(){var k;for(k in a){b(e,i,a,k)}for(k in d){b(f,c,d,k)}})}(window)); 866} 867function iOSVersion(){ 868 var agent=window.navigator.userAgent, 869 start=agent.indexOf('OS '); 870 if((agent.indexOf('iPhone')>-1 || agent.indexOf('iPad')>-1) && start>-1){ 871 return window.Number(agent.substr(start+3,3).replace('_','.')); 872 } 873 return 0; 874}
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.