1/* 2== malihu jquery custom scrollbars plugin == 3version: 2.1 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:"auto", /*mousewheel support and velocity: boolean, "auto", integer*/ 17 autoDraggerLength:true, /*auto-adjust scrollbar dragger length: boolean*/ 18 scrollButtons:{ /*scroll buttons*/ 19 enable:false, /*scroll buttons support: boolean*/ 20 scrollType:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/ 21 scrollSpeed:20, /*scroll buttons continuous scrolling speed: integer*/ 22 scrollAmount:40 /*scroll buttons pixels scroll amount: integer (pixels)*/ 23 }, 24 advanced:{ 25 updateOnBrowserResize:true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/ 26 updateOnContentResize:false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/ 27 autoExpandHorizontalScroll:false /*auto-expand width for horizontal scrolling: boolean*/ 28 }, 29 callbacks:{ 30 onScroll:function(){}, /*user custom callback function on scroll event*/ 31 onTotalScroll:function(){}, /*user custom callback function on scroll end reached event*/ 32 onTotalScrollOffset:0 /*scroll end reached offset: integer (pixels)*/ 33 } 34 }, 35 options=$.extend(true,defaults,options); 36 /*check for touch device*/ 37 $(document).data("mCS-is-touch-device",false); 38 if(is_touch_device()){ 39 $(document).data("mCS-is-touch-device",true); 40 } 41 function is_touch_device(){ 42 return !!("ontouchstart" in window) ? 1 : 0; 43 } 44 return this.each(function(){ 45 var $this=$(this); 46 /*set element width/height, create markup for custom scrollbars, add classes*/ 47 if(options.set_width){ 48 $this.css("width",options.set_width); 49 } 50 if(options.set_height){ 51 $this.css("height",options.set_height); 52 } 53 if(!$(document).data("mCustomScrollbar-index")){ 54 $(document).data("mCustomScrollbar-index","1"); 55 }else{ 56 var mCustomScrollbarIndex=parseInt($(document).data("mCustomScrollbar-index")); 57 $(document).data("mCustomScrollbar-index",mCustomScrollbarIndex+1); 58 } 59 $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")); 60 var mCustomScrollBox=$this.children(".mCustomScrollBox"); 61 if(options.horizontalScroll){ 62 mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />"); 63 var mCSB_h_wrapper=mCustomScrollBox.children(".mCSB_h_wrapper"); 64 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(); 65 }else{ 66 mCustomScrollBox.wrapInner("<div class='mCSB_container' style='position:relative; top:0;' />"); 67 } 68 var mCSB_container=mCustomScrollBox.children(".mCSB_container"); 69 if(!$(document).data("mCS-is-touch-device")){ /*not touch device - apply custom scrollbars functionality*/ 70 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>"); 71 var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), 72 mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), 73 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); 74 if(options.horizontalScroll){ 75 mCSB_dragger.data("minDraggerWidth",mCSB_dragger.width()); 76 }else{ 77 mCSB_dragger.data("minDraggerHeight",mCSB_dragger.height()); 78 } 79 if(options.scrollButtons.enable){ 80 if(options.horizontalScroll){
81 mCSB_scrollTools.prepend("<a class='mCSB_buttonLeft' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonRight' style='display:block; position:relative;'></a>"); 82 }else{ 83 mCSB_scrollTools.prepend("<a class='mCSB_buttonUp' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonDown' style='display:block; position:relative;'></a>"); 84 } 85 } 86 /*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/ 87 mCustomScrollBox.bind("scroll",function(){ 88 mCustomScrollBox.scrollTop(0).scrollLeft(0); 89 }); 90 /*store element options and update element*/ 91 $this.data({ 92 "horizontalScroll":options.horizontalScroll, 93 "scrollInertia":options.scrollInertia, 94 "scrollEasing":options.scrollEasing, 95 "mouseWheel":options.mouseWheel, 96 "autoDraggerLength":options.autoDraggerLength, 97 "scrollButtons-enable":options.scrollButtons.enable, 98 "scrollButtons-scrollType":options.scrollButtons.scrollType, 99 "scrollButtons-scrollSpeed":options.scrollButtons.scrollSpeed, 100 "scrollButtons-scrollAmount":options.scrollButtons.scrollAmount, 101 "autoExpandHorizontalScroll":options.advanced.autoExpandHorizontalScroll, 102 "onScroll-Callback":options.callbacks.onScroll, 103 "onTotalScroll-Callback":options.callbacks.onTotalScroll, 104 "onTotalScroll-Offset":options.callbacks.onTotalScrollOffset 105 }).mCustomScrollbar("update"); 106 /*window resize fn (for layouts based on percentages)*/ 107 if(options.advanced.updateOnBrowserResize){ 108 var mCSB_resizeTimeout; 109 $(window).resize(function(){ 110 if(mCSB_resizeTimeout){ 111 clearTimeout(mCSB_resizeTimeout); 112 } 113 mCSB_resizeTimeout=setTimeout(function(){ 114 $this.mCustomScrollbar("update"); 115 },150); 116 }); 117 } 118 }else{ /*is touch device*/ 119 /*check for mobile os/browser not supporting overflow:auto (Android 2.xx)*/ 120 var ua=navigator.userAgent; 121 if(ua.indexOf("Android")!=-1){ 122 var androidversion=parseFloat(ua.slice(ua.indexOf("Android")+8)); 123 if(androidversion<3){ 124 touchScroll("mCSB_"+$(document).data("mCustomScrollbar-index")); /*non overflow:auto fn*/ 125 }else{ 126 mCustomScrollBox.css({"overflow":"auto","-webkit-overflow-scrolling":"touch"}); 127 } 128 }else{ 129 mCustomScrollBox.css({"overflow":"auto","-webkit-overflow-scrolling":"touch"}); 130 } 131 mCSB_container.addClass("mCS_no_scrollbar mCS_touch"); 132 $this.data({ 133 "horizontalScroll":options.horizontalScroll, 134 "scrollInertia":options.scrollInertia, 135 "scrollEasing":options.scrollEasing, 136 "autoExpandHorizontalScroll":options.advanced.autoExpandHorizontalScroll, 137 "onScroll-Callback":options.callbacks.onScroll, 138 "onTotalScroll-Callback":options.callbacks.onTotalScroll, 139 "onTotalScroll-Offset":options.callbacks.onTotalScrollOffset 140 }); 141 mCustomScrollBox.scroll(function(){ 142 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); /*user custom callback functions*/ 143 }); 144 /*non overflow:auto fn 145 (source: http://chris-barr.com/index.php/entry/scrolling_a_overflowauto_element_on_a_touch_screen_device/)*/ 146 function touchScroll(id){ 147 var el=document.getElementById(id), 148 scrollStartPosY=0, 149 scrollStartPosX=0; 150 document.getElementById(id).addEventListener("touchstart",function(event){ 151 scrollStartPosY=this.scrollTop+event.touches[0].pageY; 152 scrollStartPosX=this.scrollLeft+event.touches[0].pageX; 153 /*event.preventDefault(); // Keep this remarked so you can click on buttons and links in the div*/ 154 },false); 155 document.getElementById(id).addEventListener("touchmove",function(event){ 156 /*These if statements allow the full page to scroll (not just the div) if they are 157 at the top of the div scroll or the bottom of the div scroll 158 The -5 and +5 below are in case they are trying to scroll the page sideways 159 but their finger moves a few pixels down or up. The event.preventDefault() function 160 will not be called in that case so that the whole page can scroll.*/ 161 if((this.scrollTop<this.scrollHeight-this.offsetHeight && this.scrollTop+event.touches[0].pageY<scrollStartPosY-5) || (this.scrollTop!=0 && this.scrollTop+event.touches[0].pageY>scrollStartPosY+5)) 162 event.preventDefault(); 163 if((this.scrollLeft<this.scrollWidth-this.offsetWidth && this.scrollLeft+event.touches[0].pageX < scrollStartPosX-5
163) || (this.scrollLeft!=0&&this.scrollLeft+event.touches[0].pageX>scrollStartPosX+5)) 164 event.preventDefault(); 165 this.scrollTop=scrollStartPosY-event.touches[0].pageY; 166 this.scrollLeft=scrollStartPosX-event.touches[0].pageX; 167 },false); 168 } 169 } 170 /*content resize fn (for dynamically generated content)*/ 171 if(options.advanced.updateOnContentResize){ 172 var mCSB_onContentResize; 173 if(options.horizontalScroll){ 174 var mCSB_containerOldSize=mCSB_container.outerWidth(); 175 if(is_touch_device()){ 176 /*disable iOS webkit inertia for smooth scrolling*/ 177 mCustomScrollBox.css({"-webkit-overflow-scrolling":"auto"}); 178 } 179 }else{ 180 var mCSB_containerOldSize=mCSB_container.outerHeight(); 181 } 182 mCSB_onContentResize=setInterval(function(){ 183 if(options.horizontalScroll){ 184 if(options.advanced.autoExpandHorizontalScroll){ 185 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(); 186 } 187 var mCSB_containerNewSize=mCSB_container.outerWidth(); 188 }else{ 189 var mCSB_containerNewSize=mCSB_container.outerHeight(); 190 } 191 if(mCSB_containerNewSize!=mCSB_containerOldSize){ 192 $this.mCustomScrollbar("update"); 193 mCSB_containerOldSize=mCSB_containerNewSize; 194 } 195 },300); 196 } 197 }); 198 }, 199 update:function(){ 200 var $this=$(this), 201 mCustomScrollBox=$this.children(".mCustomScrollBox"), 202 mCSB_container=mCustomScrollBox.children(".mCSB_container"); 203 if(!$(document).data("mCS-is-touch-device")){ 204 mCSB_container.removeClass("mCS_no_scrollbar"); 205 } 206 var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"), 207 mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"), 208 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); 209 if($this.data("horizontalScroll")){ 210 var mCSB_buttonLeft=mCSB_scrollTools.children(".mCSB_buttonLeft"), 211 mCSB_buttonRight=mCSB_scrollTools.children(".mCSB_buttonRight"), 212 mCustomScrollBoxW=mCustomScrollBox.width(); 213 if($this.data("autoExpandHorizontalScroll")){ 214 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(); 215 } 216 var mCSB_containerW=mCSB_container.outerWidth(); 217 }else{ 218 var mCSB_buttonUp=mCSB_scrollTools.children(".mCSB_buttonUp"), 219 mCSB_buttonDown=mCSB_scrollTools.children(".mCSB_buttonDown"), 220 mCustomScrollBoxH=mCustomScrollBox.height(), 221 mCSB_containerH=mCSB_container.outerHeight(); 222 } 223 if(mCSB_containerH>mCustomScrollBoxH && !$this.data("horizontalScroll") && !$(document).data("mCS-is-touch-device")){ /*content needs vertical scrolling*/ 224 mCSB_scrollTools.css("display","block"); 225 var mCSB_draggerContainerH=mCSB_draggerContainer.height(); 226 /*auto adjust scrollbar dragger length analogous to content*/ 227 if($this.data("autoDraggerLength")){ 228 var draggerH=Math.round(mCustomScrollBoxH/mCSB_containerH*mCSB_draggerContainerH), 229 minDraggerH=mCSB_dragger.data("minDraggerHeight"); 230 if(draggerH<=minDraggerH){ /*min dragger height*/ 231 mCSB_dragger.css({"height":minDraggerH}); 232 }else if(draggerH>=mCSB_draggerContainerH-10){ /*max dragger height*/ 233 var mCSB_draggerContainerMaxH=mCSB_draggerContainerH-10; 234 mCSB_dragger.css({"height":mCSB_draggerContainerMaxH}); 235 }else{ 236 mCSB_dragger.css({"height":draggerH}); 237 } 238 mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height":mCSB_dragger.height()+"px"}); 239 } 240 var mCSB_draggerH=mCSB_dragger.height(), 241 /*calculate and store scroll amount*/ 242 scrollAmount=(mCSB_containerH-mCustomScrollBoxH)/(mCSB_draggerContainerH-mCSB_draggerH); 243 $this.data("scrollAmount",scrollAmount); 244 /*add scrolling*/ 245 $this.mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); 246 /*scroll*/ 247 var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().top)); 248 $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false}); 249 }else if(mCSB_containerW>mCustomScrollBoxW && $this.data("horizontalScroll") && !$(document).data("mCS-is-touch-device")){ /*content needs horizontal scrolling*/ 250 mCSB_scrollTools.css("display","block"); 251 var mCSB_draggerContainerW=mCSB_draggerContainer.width(); 252 /*auto adjust scrollbar dragger length analogous to content*/ 253 if($this.data("autoDraggerLength")){ 254 var draggerW=Math.round(mCustomScrollBoxW/mCSB_containerW*mCSB_draggerContainerW), 255 minDraggerW=mCSB_dragger.data("minDraggerWidth"); 256 if(draggerW<=minDraggerW){ /*min dragger height*/ 257 mCSB_dragger.css({"width":minDraggerW}); 258 }else if(draggerW>=mCSB_draggerContainerW-10){ /*max dragger height*/ 259 var mCSB_draggerContainerMaxW=mCSB_draggerContainerW-10; 260 mCSB_dragger.css({"width":mCSB_draggerContainerMaxW}); 261 }else{ 262 mCSB_dragger.css({"width":draggerW}); 263 } 264 } 265 var mCSB_draggerW=mCSB_dragger.width(), 266 /*calculate and store scroll amount*/ 267 scrollAmount=(mCSB_containerW-mCustomScrollBoxW)/(mCSB_draggerContainerW-mCSB_draggerW); 268 $this.data("scrollAmount",scrollAmount); 269 /*add scrolling*/ 270 $this.mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight); 271 /*scroll*/ 272 var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().left)); 273 $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false}); 274 }else{ /*content does not need scrolling*/ 275 /*unbind events, reset content position, hide scrollbars, remove classes*/ 276 mCustomScrollBox.unbind("mousewheel"); 277 mCustomScrollBox.unbind("focusin"); 278 if($this.data("horizontalScroll")){ 279 mCSB_dragger.add(mCSB_container).css("left",0); 280 }else{ 281 mCSB_dragger.add(mCSB_container).css("top",0); 282 } 283 mCSB_scrollTools.css("display","none"); 284 mCSB_container.addClass("mCS_no_scrollbar"); 285 } 286 }, 287 scrolling:function(mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight){ 288 var $this=$(this); 289 /*drag scrolling*/ 290 if(!mCSB_dragger.hasClass("ui-draggable")){ /*apply drag function once*/ 291 if($this.data("horizontalScroll")){ 292 var draggableAxis="x"; 293 }else{ 294 var draggableAxis="y"; 295 } 296 mCSB_dragger.draggable({ 297 axis:draggableAxis, 298 containment:"parent", 299 drag:function(event,ui){ 300 $this.mCustomScrollbar("scroll"); 301 mCSB_dragger.addClass("mCSB_dragger_onDrag"); 302 }, 303 stop:function(event,ui){ 304 mCSB_dragger.removeClass("mCSB_dragger_onDrag"); 305 } 306 }); 307 } 308 mCSB_draggerContainer.unbind("click").bind("click",function(e){
309 if($this.data("horizontalScroll")){ 310 var mouseCoord=(e.pageX-mCSB_draggerContainer.offset().left); 311 if(mouseCoord<mCSB_dragger.position().left || mouseCoord>(mCSB_dragger.position().left+mCSB_dragger.width())){ 312 var scrollToPos=mouseCoord; 313 if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 314 scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width(); 315 } 316 mCSB_dragger.css("left",scrollToPos); 317 $this.mCustomScrollbar("scroll"); 318 } 319 }else{ 320 var mouseCoord=(e.pageY-mCSB_draggerContainer.offset().top); 321 if(mouseCoord<mCSB_dragger.position().top || mouseCoord>(mCSB_dragger.position().top+mCSB_dragger.height())){ 322 var scrollToPos=mouseCoord; 323 if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 324 scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height(); 325 } 326 mCSB_dragger.css("top",scrollToPos); 327 $this.mCustomScrollbar("scroll"); 328 } 329 } 330 }); 331 /*mousewheel scrolling*/ 332 if($this.data("mouseWheel")){ 333 var mousewheelVel=$this.data("mouseWheel"); 334 if($this.data("mouseWheel")==="auto"){ 335 mousewheelVel=8; /*default mousewheel velocity*/ 336 /*check for safari browser on mac osx to lower mousewheel velocity*/ 337 var os=navigator.userAgent; 338 if(os.indexOf("Mac")!=-1 && os.indexOf("Safari")!=-1 && os.indexOf("AppleWebKit")!=-1 && os.indexOf("Chrome")==-1){ 339 mousewheelVel=1; 340 } 341 } 342 mCustomScrollBox.unbind("mousewheel").bind("mousewheel",function(event,delta){ 343 event.preventDefault(); 344 var vel=Math.abs(delta*mousewheelVel); 345 if($this.data("horizontalScroll")){ 346 var posX=mCSB_dragger.position().left-(delta*vel); 347 mCSB_dragger.css("left",posX); 348 if(mCSB_dragger.position().left<0){ 349 mCSB_dragger.css("left",0); 350 } 351 var mCSB_draggerContainerW=mCSB_draggerContainer.width(), 352 mCSB_draggerW=mCSB_dragger.width(); 353 if(mCSB_dragger.position().left>mCSB_draggerContainerW-mCSB_draggerW){ 354 mCSB_dragger.css("left",mCSB_draggerContainerW-mCSB_draggerW); 355 } 356 }else{ 357 var posY=mCSB_dragger.position().top-(delta*vel); 358 mCSB_dragger.css("top",posY); 359 if(mCSB_dragger.position().top<0){ 360 mCSB_dragger.css("top",0); 361 } 362 var mCSB_draggerContainerH=mCSB_draggerContainer.height(), 363 mCSB_draggerH=mCSB_dragger.height(); 364 if(mCSB_dragger.position().top>mCSB_draggerContainerH-mCSB_draggerH){ 365 mCSB_dragger.css("top",mCSB_draggerContainerH-mCSB_draggerH); 366 } 367 } 368 $this.mCustomScrollbar("scroll"); 369 }); 370 } 371 /*buttons scrolling*/ 372 if($this.data("scrollButtons-enable")){ 373 if($this.data("scrollButtons-scrollType")==="pixels"){ /*scroll by pixels*/ 374 var pixelsScrollTo; 375 if($.browser.msie && parseInt($.browser.version)<9){ /*stupid ie8*/ 376 $this.data("scrollInertia",0); 377 } 378 if($this.data("horizontalScroll")){ 379 mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click mousedown mouseup mouseout",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); 380 /*scroll right*/ 381 mCSB_buttonRight.bind("click",function(e){ 382 e.preventDefault(); 383 if(!mCSB_container.is(":animated")){ 384 pixelsScrollTo=Math.abs(mCSB_container.position().left)+$this.data("scrollButtons-scrollAmount"); 385 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 386 } 387 }); 388 /*scroll left*/ 389 mCSB_buttonLeft.bind("click",function(e){ 390 e.preventDefault(); 391 if(!mCSB_container.is(":animated")){ 392 pixelsScrollTo=Math.abs(mCSB_container.position().left)-$this.data("scrollButtons-scrollAmount"); 393 if(mCSB_container.position().left>=-$this.data("scrollButtons-scrollAmount")){ 394 pixelsScrollTo="left"; 395 } 396 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 397 } 398 }); 399 }else{ 400 mCSB_buttonDown.add(mCSB_buttonUp).unbind("click mousedown mouseup mouseout",mCSB_buttonDown_stop,mCSB_buttonUp_stop); 401 /*scroll down*/ 402 mCSB_buttonDown.bind("click",function(e){
403 e.preventDefault(); 404 if(!mCSB_container.is(":animated")){ 405 pixelsScrollTo=Math.abs(mCSB_container.position().top)+$this.data("scrollButtons-scrollAmount"); 406 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 407 } 408 }); 409 /*scroll up*/ 410 mCSB_buttonUp.bind("click",function(e){ 411 e.preventDefault(); 412 if(!mCSB_container.is(":animated")){ 413 pixelsScrollTo=Math.abs(mCSB_container.position().top)-$this.data("scrollButtons-scrollAmount"); 414 if(mCSB_container.position().top>=-$this.data("scrollButtons-scrollAmount")){ 415 pixelsScrollTo="top"; 416 } 417 $this.mCustomScrollbar("scrollTo",pixelsScrollTo); 418 } 419 }); 420 } 421 }else{ /*continuous scrolling*/ 422 if($this.data("horizontalScroll")){ 423 mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click mousedown mouseup mouseout",mCSB_buttonRight_stop,mCSB_buttonLeft_stop); 424 /*scroll right*/ 425 var mCSB_buttonScrollRight, 426 mCSB_draggerContainerW=mCSB_draggerContainer.width(), 427 mCSB_draggerW=mCSB_dragger.width(); 428 mCSB_buttonRight.bind("mousedown",function(e){ 429 e.preventDefault(); 430 var draggerScrollTo=mCSB_draggerContainerW-mCSB_draggerW; 431 mCSB_buttonScrollRight=setInterval(function(){ 432 var scrollToSpeed=Math.abs(mCSB_dragger.position().left-draggerScrollTo)*(100/$this.data("scrollButtons-scrollSpeed")); 433 mCSB_dragger.stop().animate({left:draggerScrollTo},scrollToSpeed,"linear"); 434 $this.mCustomScrollbar("scroll"); 435 },20); 436 }); 437 var mCSB_buttonRight_stop=function(e){ 438 e.preventDefault(); 439 clearInterval(mCSB_buttonScrollRight); 440 mCSB_dragger.stop(); 441 } 442 mCSB_buttonRight.bind("mouseup mouseout",mCSB_buttonRight_stop); 443 /*scroll left*/ 444 var mCSB_buttonScrollLeft; 445 mCSB_buttonLeft.bind("mousedown",function(e){ 446 e.preventDefault(); 447 var draggerScrollTo=0; 448 mCSB_buttonScrollLeft=setInterval(function(){ 449 var scrollToSpeed=Math.abs(mCSB_dragger.position().left-draggerScrollTo)*(100/$this.data("scrollButtons-scrollSpeed")); 450 mCSB_dragger.stop().animate({left:draggerScrollTo},scrollToSpeed,"linear"); 451 $this.mCustomScrollbar("scroll"); 452 },20); 453 }); 454 var mCSB_buttonLeft_stop=function(e){ 455 e.preventDefault(); 456 clearInterval(mCSB_buttonScrollLeft); 457 mCSB_dragger.stop(); 458 } 459 mCSB_buttonLeft.bind("mouseup mouseout",mCSB_buttonLeft_stop); 460 }else{ 461 mCSB_buttonDown.add(mCSB_buttonUp).unbind("click mousedown mouseup mouseout",mCSB_buttonDown_stop,mCSB_buttonUp_stop); 462 /*scroll down*/ 463 var mCSB_buttonScrollDown, 464 mCSB_draggerContainerH=mCSB_draggerContainer.height(), 465 mCSB_draggerH=mCSB_dragger.height(); 466 mCSB_buttonDown.bind("mousedown",function(e){ 467 e.preventDefault(); 468 var draggerScrollTo=mCSB_draggerContainerH-mCSB_draggerH; 469 mCSB_buttonScrollDown=setInterval(function(){ 470 var scrollToSpeed=Math.abs(mCSB_dragger.position().top-draggerScrollTo)*(100/$this.data("scrollButtons-scrollSpeed")); 471 mCSB_dragger.stop().animate({top:draggerScrollTo},scrollToSpeed,"linear"); 472 $this.mCustomScrollbar("scroll"); 473 },20); 474 }); 475 var mCSB_buttonDown_stop=function(e){ 476 e.preventDefault(); 477 clearInterval(mCSB_buttonScrollDown); 478 mCSB_dragger.stop(); 479 } 480 mCSB_buttonDown.bind("mouseup mouseout",mCSB_buttonDown_stop); 481 /*scroll up*/ 482 var mCSB_buttonScrollUp; 483 mCSB_buttonUp.bind("mousedown",function(e){ 484 e.preventDefault(); 485 var draggerScrollTo=0; 486 mCSB_buttonScrollUp=setInterval(function(){ 487 var scrollToSpeed=Math.abs(mCSB_dragger.position().top-draggerScrollTo)*(100/$this.data("scrollButtons-scrollSpeed")); 488 mCSB_dragger.stop().animate({top:draggerScrollTo},scrollToSpeed,"linear"); 489 $this.mCustomScrollbar("scroll"); 490 },20); 491 }); 492 var mCSB_buttonUp_stop=function(e){
493 e.preventDefault(); 494 clearInterval(mCSB_buttonScrollUp); 495 mCSB_dragger.stop(); 496 } 497 mCSB_buttonUp.bind("mouseup mouseout",mCSB_buttonUp_stop); 498 } 499 } 500 } 501 /*scrolling on element focus (e.g. via TAB key)*/ 502 mCustomScrollBox.unbind("focusin").bind("focusin",function(){ 503 mCustomScrollBox.scrollTop(0).scrollLeft(0); 504 var focusedElem=$(document.activeElement); 505 if(focusedElem.is("input,textarea,select,button,a[tabindex],area,object")){ 506 if($this.data("horizontalScroll")){ 507 var mCSB_containerX=mCSB_container.position().left, 508 focusedElemX=focusedElem.position().left, 509 mCustomScrollBoxW=mCustomScrollBox.width(), 510 focusedElemW=focusedElem.outerWidth(); 511 if(mCSB_containerX+focusedElemX>=0 && mCSB_containerX+focusedElemX<=mCustomScrollBoxW-focusedElemW){ 512 /*just focus...*/ 513 }else{ /*scroll, then focus*/ 514 var moveDragger=focusedElemX/$this.data("scrollAmount"); 515 if(moveDragger>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 516 moveDragger=mCSB_draggerContainer.width()-mCSB_dragger.width(); 517 } 518 mCSB_dragger.css("left",moveDragger); 519 $this.mCustomScrollbar("scroll"); 520 } 521 }else{ 522 var mCSB_containerY=mCSB_container.position().top, 523 focusedElemY=focusedElem.position().top, 524 mCustomScrollBoxH=mCustomScrollBox.height(), 525 focusedElemH=focusedElem.outerHeight(); 526 if(mCSB_containerY+focusedElemY>=0 && mCSB_containerY+focusedElemY<=mCustomScrollBoxH-focusedElemH){ 527 /*just focus...*/ 528 }else{ /*scroll, then focus*/ 529 var moveDragger=focusedElemY/$this.data("scrollAmount"); 530 if(moveDragger>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 531 moveDragger=mCSB_draggerContainer.height()-mCSB_dragger.height(); 532 } 533 mCSB_dragger.css("top",moveDragger); 534 $this.mCustomScrollbar("scroll"); 535 } 536 } 537 } 538 }); 539 }, 540 scroll:function(updated){ 541 var $this=$(this), 542 mCSB_dragger=$this.find(".mCSB_dragger"), 543 mCSB_container=$this.find(".mCSB_container"), 544 mCustomScrollBox=$this.find(".mCustomScrollBox"); 545 if($this.data("horizontalScroll")){ 546 var draggerX=mCSB_dragger.position().left, 547 targX=-draggerX*$this.data("scrollAmount"), 548 thisX=mCSB_container.position().left, 549 posX=Math.round(thisX-targX); 550 }else{ 551 var draggerY=mCSB_dragger.position().top, 552 targY=-draggerY*$this.data("scrollAmount"), 553 thisY=mCSB_container.position().top, 554 posY=Math.round(thisY-targY); 555 } 556 if($.browser.webkit){ /*fix webkit zoom and jquery animate*/ 557 var screenCssPixelRatio=(window.outerWidth-8)/window.innerWidth, 558 isZoomed=(screenCssPixelRatio<.98 || screenCssPixelRatio>1.02); 559 } 560 if($this.data("scrollInertia")===0 || isZoomed){ 561 if($this.data("horizontalScroll")){ 562 mCSB_container.css("left",targX); 563 }else{ 564 mCSB_container.css("top",targY); 565 } 566 if(!updated){ 567 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); /*user custom callback functions*/ 568 } 569 }else{ 570 if($this.data("horizontalScroll")){ 571 mCSB_container.stop().animate({left: "-="+posX},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 572 if(!updated){ 573 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); /*user custom callback functions*/ 574 } 575 }); 576 }else{ 577 mCSB_container.stop().animate({top: "-="+posY},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 578 if(!updated){ 579 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); /*user custom callback functions*/ 580 } 581 }); 582 } 583 } 584 }, 585 scrollTo:function(scrollTo,options){ 586 var defaults={ 587 moveDragger:false, 588 callback:true 589 }, 590 options=$.extend(defaults,options), 591 $this=$(this), 592 scrollToPos, 593 mCustomScrollBox=$this.find(".mCustomScrollBox"), 594 mCSB_container=mCustomScrollBox.children(".mCSB_container"); 595 if(!$(document).data("mCS-is-touch-device")){ 596 var mCSB_draggerContainer=$this.find(".mCSB_draggerContainer"), 597 mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"); 598 } 599 var targetPos; 600 if(scrollTo){ 601 if(typeof(scrollTo)==="number"){ /*if integer, scroll by number of pixels*/ 602 if(options.moveDragger){ /*scroll dragger*/ 603 scrollToPos=scrollTo; 604 }else{ /*scroll content by default*/ 605 targetPos=scrollTo; 606 scrollToPos=Math.round(targetPos/$this.data("scrollAmount"));
607 } 608 }else if(typeof(scrollTo)==="string"){ /*if string, scroll by element position*/ 609 var target; 610 if(scrollTo==="top"){ /*scroll to top*/ 611 target=0; 612 }else if(scrollTo==="bottom" && !$this.data("horizontalScroll")){ /*scroll to bottom*/ 613 target=mCSB_container.outerHeight()-mCustomScrollBox.height(); 614 }else if(scrollTo==="left"){ /*scroll to left*/ 615 target=0; 616 }else if(scrollTo==="right" && $this.data("horizontalScroll")){ /*scroll to right*/ 617 target=mCSB_container.outerWidth()-mCustomScrollBox.width(); 618 }else if(scrollTo==="first"){ /*scroll to first element position*/ 619 target=$this.find(".mCSB_container").find(":first"); 620 }else if(scrollTo==="last"){ /*scroll to last element position*/ 621 target=$this.find(".mCSB_container").find(":last"); 622 }else{ /*scroll to element position*/ 623 target=$this.find(scrollTo); 624 } 625 if(target.length===1){ /*if such unique element exists, scroll to it*/ 626 if($this.data("horizontalScroll")){ 627 targetPos=target.position().left; 628 }else{ 629 targetPos=target.position().top; 630 } 631 if($(document).data("mCS-is-touch-device")){ 632 scrollToPos=targetPos; 633 }else{ 634 scrollToPos=Math.ceil(targetPos/$this.data("scrollAmount")); 635 } 636 }else{ 637 scrollToPos=target; 638 } 639 } 640 /*scroll to*/ 641 if($(document).data("mCS-is-touch-device")){ /*is touch device*/ 642 if($this.data("horizontalScroll")){ 643 mCustomScrollBox.stop().animate({scrollLeft:scrollToPos},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 644 if(options.callback){ 645 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); 646 } 647 }); 648 }else{ 649 mCustomScrollBox.stop().animate({scrollTop:scrollToPos},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){ 650 if(options.callback){ 651 $this.mCustomScrollbar("callbacks",mCustomScrollBox,mCSB_container); 652 } 653 }); 654 } 655 }else{ /*not touch device*/ 656 if(scrollToPos<0){ 657 scrollToPos=0; 658 } 659 if($this.data("horizontalScroll")){ 660 if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/ 661 scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width(); 662 } 663 mCSB_dragger.css("left",scrollToPos); 664 }else{ 665 if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/ 666 scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height(); 667 } 668 mCSB_dragger.css("top",scrollToPos); 669 } 670 if(options.callback){ 671 $this.mCustomScrollbar("scroll"); 672 }else{ 673 $this.mCustomScrollbar("scroll",true); 674 } 675 } 676 677 } 678 }, 679 callbacks:function(mCustomScrollBox,mCSB_container){ 680 var $this=$(this); 681 if(!$(document).data("mCS-is-touch-device")){ /*not touch device*/ 682 if($this.data("horizontalScroll")){ 683 var mCSB_containerX=Math.round(mCSB_container.position().left); 684 if(mCSB_containerX<0 && mCSB_containerX<=mCustomScrollBox.width()-mCSB_container.outerWidth()+$this.data("onTotalScroll-Offset")){ 685 $this.data("onTotalScroll-Callback").call(); 686 }else{ 687 $this.data("onScroll-Callback").call(); 688 } 689 }else{ 690 var mCSB_containerY=Math.round(mCSB_container.position().top); 691 if(mCSB_containerY<0 && mCSB_containerY<=mCustomScrollBox.height()-mCSB_container.outerHeight()+$this.data("onTotalScroll-Offset")){ 692 $this.data("onTotalScroll-Callback").call(); 693 }else{ 694 $this.data("onScroll-Callback").call(); 695 } 696 } 697 }else{ /*is touch device*/ 698 if($this.data("horizontalScroll")){ 699 var mCustomScrollBoxX=Math.round(mCustomScrollBox.scrollLeft()); 700 if(mCustomScrollBoxX>0 && mCustomScrollBoxX>=mCSB_container.outerWidth()-$this.width()-$this.data("onTotalScroll-Offset")){ 701 $this.data("onTotalScroll-Callback").call(); 702 }else{ 703 $this.data("onScroll-Callback").call(); 704 } 705 }else{ 706 var mCustomScrollBoxY=Math.round(mCustomScrollBox.scrollTop()); 707 if(mCustomScrollBoxY>0 && mCustomScrollBoxY>=mCSB_container.outerHeight()-$this.height()-$this.data("onTotalScroll-Offset")){ 708 $this.data("onTotalScroll-Callback").call(); 709 }else{ 710 $this.data("onScroll-Callback").call(); 711 } 712 } 713 } 714 } 715 }
716 $.fn.mCustomScrollbar=function(method){ 717 if(methods[method]){ 718 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 719 }else if(typeof method==="object" || !method){ 720 return methods.init.apply(this,arguments); 721 }else{ 722 $.error("Method "+method+" does not exist"); 723 } 724 }; 725})(jQuery);
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.