/* == malihu jquery custom scrollbars plugin == version: 2.3.1 author: malihu (http://manos.malihu.gr) plugin home: http://manos.malihu.gr/jquery-custom-content-scroller */ (function($){ var methods={ init:function(options){ var defaults={ set_width:false, /*optional element width: boolean, pixels, percentage*/ set_height:false, /*optional element height: boolean, pixels, percentage*/ horizontalscroll:false, /*scroll horizontally: boolean*/ scrollinertia:550, /*scrolling inertia: integer (milliseconds)*/ scrolleasing:"easeoutcirc", /*scrolling easing: string*/ mousewheel:"pixels", /*mousewheel support and velocity: boolean, "auto", integer, "pixels"*/ mousewheelpixels:60, /*mousewheel pixels amount: integer*/ autodraggerlength:true, /*auto-adjust scrollbar dragger length: boolean*/ scrollbuttons:{ /*scroll buttons*/ enable:false, /*scroll buttons support: boolean*/ scrolltype:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/ scrollspeed:20, /*scroll buttons continuous scrolling speed: integer*/ scrollamount:40 /*scroll buttons pixels scroll amount: integer (pixels)*/ }, advanced:{ updateonbrowserresize:true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/ updateoncontentresize:false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/ autoexpandhorizontalscroll:false, /*auto-expand width for horizontal scrolling: boolean*/ autoscrollonfocus:true /*auto-scroll on focused elements: boolean*/ }, callbacks:{ onscrollstart:function(){}, /*user custom callback function on scroll start event*/ onscroll:function(){}, /*user custom callback function on scroll event*/ ontotalscroll:function(){}, /*user custom callback function on scroll end reached event*/ ontotalscrollback:function(){}, /*user custom callback function on scroll begin reached event*/ ontotalscrolloffset:0, /*scroll end reached offset: integer (pixels)*/ whilescrolling:false, /*user custom callback function on scrolling event*/ whilescrollinginterval:30 /*interval for calling whilescrolling callback: integer (milliseconds)*/ } }, options=$.extend(true,defaults,options); /*check for touch device*/ $(document).data("mcs-is-touch-device",false); if(is_touch_device()){ $(document).data("mcs-is-touch-device",true); } function is_touch_device(){ return !!("ontouchstart" in window) ? 1 : 0; } return this.each(function(){ var $this=$(this); /*set element width/height, create markup for custom scrollbars, add classes*/ if(options.set_width){ $this.css("width",options.set_width); } if(options.set_height){ $this.css("height",options.set_height); } if(!$(document).data("mcustomscrollbar-index")){ $(document).data("mcustomscrollbar-index","1"); }else{ var mcustomscrollbarindex=parseint($(document).data("mcustomscrollbar-index")); $(document).data("mcustomscrollbar-index",mcustomscrollbarindex+1); } $this.wrapinner("
").addclass("mcustomscrollbar _mcs_"+$(document).data("mcustomscrollbar-index")); var mcustomscrollbox=$this.children(".mcustomscrollbox"); if(options.horizontalscroll){ mcustomscrollbox.addclass("mcsb_horizontal").wrapinner("
"); var mcsb_h_wrapper=mcustomscrollbox.children(".mcsb_h_wrapper"); mcsb_h_wrapper.wrapinner("
").children(".mcsb_container").css({"width":mcsb_h_wrapper.children().outerwidth(),"position":"relative"}).unwrap(); }else{ mcustomscrollbox.wrapinner("
"); } var mcsb_container=mcustomscrollbox.children(".mcsb_container"); if($(document).data("mcs-is-touch-device")){ mcsb_container.addclass("mcs_touch"); } mcsb_container.after("
"); var mcsb_scrolltools=mcustomscrollbox.children(".mcsb_scrolltools"), mcsb_draggercontainer=mcsb_scrolltools.children(".mcsb_draggercontainer"), mcsb_dragger=mcsb_draggercontainer.children(".mcsb_dragger"); if(options.horizontalscroll){ mcsb_dragger.data("mindraggerwidth",mcsb_dragger.width()); }else{ mcsb_dragger.data("mindraggerheight",mcsb_dragger.height()); } if(options.scrollbuttons.enable){ if(options.horizontalscroll){ mcsb_scrolltools.prepend("").append(""); }else{ mcsb_scrolltools.prepend("").append(""); } } /*mcustomscrollbox scrolltop and scrollleft is always 0 to prevent browser focus scrolling*/ mcustomscrollbox.bind("scroll",function(){ if(!$this.is(".mcs_disabled")){ /*native focus scrolling for disabled scrollbars*/ mcustomscrollbox.scrolltop(0).scrollleft(0); } }); /*store options, global vars/states, intervals and update element*/ $this.data({ /*init state*/ "mcs_init":true, /*option parameters*/ "horizontalscroll":options.horizontalscroll, "scrollinertia":options.scrollinertia, "scrolleasing":options.scrolleasing, "mousewheel":options.mousewheel, "mousewheelpixels":options.mousewheelpixels, "autodraggerlength":options.autodraggerlength, "scrollbuttons_enable":options.scrollbuttons.enable, "scrollbuttons_scrolltype":options.scrollbuttons.scrolltype, "scrollbuttons_scrollspeed":options.scrollbuttons.scrollspeed, "scrollbuttons_scrollamount":options.scrollbuttons.scrollamount, "autoexpandhorizontalscroll":options.advanced.autoexpandhorizontalscroll, "autoscrollonfocus":options.advanced.autoscrollonfocus, "onscrollstart_callback":options.callbacks.onscrollstart, "onscroll_callback":options.callbacks.onscroll, "ontotalscroll_callback":options.callbacks.ontotalscroll, "ontotalscrollback_callback":options.callbacks.ontotalscrollback, "ontotalscroll_offset":options.callbacks.ontotalscrolloffset, "whilescrolling_callback":options.callbacks.whilescrolling, "whilescrolling_interval":options.callbacks.whilescrollinginterval, /*events binding state*/ "bindevent_scrollbar_click":false, "bindevent_mousewheel":false, "bindevent_focusin":false, "bindevent_buttonscontinuous_y":false, "bindevent_buttonscontinuous_x":false, "bindevent_buttonspixels_y":false, "bindevent_buttonspixels_x":false, "bindevent_scrollbar_touch":false, "bindevent_content_touch":false, /*buttons intervals*/ "mcsb_buttonscrollright":false, "mcsb_buttonscrollleft":false, "mcsb_buttonscrolldown":false, "mcsb_buttonscrollup":false, /*callback intervals*/ "whilescrolling":false }).mcustomscrollbar("update"); /*detect max-width*/ if(options.horizontalscroll){ if($this.css("max-width")!=="none"){ if(!options.advanced.updateoncontentresize){ /*needs updateoncontentresize*/ options.advanced.updateoncontentresize=true; } $this.data({"mcs_maxwidth":parseint($this.css("max-width")),"mcs_maxwidth_interval":setinterval(function(){ if(parseint($this.css("width"))>$this.data("mcs_maxwidth")){ clearinterval($this.data("mcs_maxwidth_interval")); $this.mcustomscrollbar("update"); } },150)}); } }else{ /*detect max-height*/ if($this.css("max-height")!=="none"){ $this.data({"mcs_maxheight":parseint($this.css("max-height")),"mcs_maxheight_interval":setinterval(function(){ mcustomscrollbox.css("max-height",$this.data("mcs_maxheight")); if(parseint($this.css("height"))>$this.data("mcs_maxheight")){ clearinterval($this.data("mcs_maxheight_interval")); $this.mcustomscrollbar("update"); } },150)}); } } /*window resize fn (for layouts based on percentages)*/ if(options.advanced.updateonbrowserresize){ var mcsb_resizetimeout; $(window).resize(function(){ if(mcsb_resizetimeout){ cleartimeout(mcsb_resizetimeout); } mcsb_resizetimeout=settimeout(function(){ if(!$this.is(".mcs_disabled") && !$this.is(".mcs_destroyed")){ $this.mcustomscrollbar("update"); } },150); }); } /*content resize fn (for dynamically generated content)*/ if(options.advanced.updateoncontentresize){ var mcsb_oncontentresize; if(options.horizontalscroll){ var mcsb_containeroldsize=mcsb_container.outerwidth(); }else{ var mcsb_containeroldsize=mcsb_container.outerheight(); } mcsb_oncontentresize=setinterval(function(){ if(options.horizontalscroll){ if(options.advanced.autoexpandhorizontalscroll){ mcsb_container.css({"position":"absolute","width":"auto"}).wrap("
").css({"width":mcsb_container.outerwidth(),"position":"relative"}).unwrap(); } var mcsb_containernewsize=mcsb_container.outerwidth(); }else{ var mcsb_containernewsize=mcsb_container.outerheight(); } if(mcsb_containernewsize!=mcsb_containeroldsize){ $this.mcustomscrollbar("update"); mcsb_containeroldsize=mcsb_containernewsize; } },300); } }); }, update:function(){ var $this=$(this), mcustomscrollbox=$this.children(".mcustomscrollbox"), mcsb_container=mcustomscrollbox.children(".mcsb_container"); mcsb_container.removeclass("mcs_no_scrollbar"); $this.removeclass("mcs_disabled mcs_destroyed"); mcustomscrollbox.scrolltop(0).scrollleft(0); /*reset scrolltop/scrollleft to prevent browser focus scrolling*/ var mcsb_scrolltools=mcustomscrollbox.children(".mcsb_scrolltools"), mcsb_draggercontainer=mcsb_scrolltools.children(".mcsb_draggercontainer"), mcsb_dragger=mcsb_draggercontainer.children(".mcsb_dragger"); if($this.data("horizontalscroll")){ var mcsb_buttonleft=mcsb_scrolltools.children(".mcsb_buttonleft"), mcsb_buttonright=mcsb_scrolltools.children(".mcsb_buttonright"), mcustomscrollboxw=mcustomscrollbox.width(); if($this.data("autoexpandhorizontalscroll")){ mcsb_container.css({"position":"absolute","width":"auto"}).wrap("
").css({"width":mcsb_container.outerwidth(),"position":"relative"}).unwrap(); } var mcsb_containerw=mcsb_container.outerwidth(); }else{ var mcsb_buttonup=mcsb_scrolltools.children(".mcsb_buttonup"), mcsb_buttondown=mcsb_scrolltools.children(".mcsb_buttondown"), mcustomscrollboxh=mcustomscrollbox.height(), mcsb_containerh=mcsb_container.outerheight(); } if(mcsb_containerh>mcustomscrollboxh && !$this.data("horizontalscroll")){ /*content needs vertical scrolling*/ mcsb_scrolltools.css("display","block"); var mcsb_draggercontainerh=mcsb_draggercontainer.height(); /*auto adjust scrollbar dragger length analogous to content*/ if($this.data("autodraggerlength")){ var draggerh=math.round(mcustomscrollboxh/mcsb_containerh*mcsb_draggercontainerh), mindraggerh=mcsb_dragger.data("mindraggerheight"); if(draggerh<=mindraggerh){ /*min dragger height*/ mcsb_dragger.css({"height":mindraggerh}); }else if(draggerh>=mcsb_draggercontainerh-10){ /*max dragger height*/ var mcsb_draggercontainermaxh=mcsb_draggercontainerh-10; mcsb_dragger.css({"height":mcsb_draggercontainermaxh}); }else{ mcsb_dragger.css({"height":draggerh}); } mcsb_dragger.children(".mcsb_dragger_bar").css({"line-height":mcsb_dragger.height()+"px"}); } var mcsb_draggerh=mcsb_dragger.height(), /*calculate and store scroll amount, add scrolling*/ scrollamount=(mcsb_containerh-mcustomscrollboxh)/(mcsb_draggercontainerh-mcsb_draggerh); $this.data("scrollamount",scrollamount).mcustomscrollbar("scrolling",mcustomscrollbox,mcsb_container,mcsb_draggercontainer,mcsb_dragger,mcsb_buttonup,mcsb_buttondown,mcsb_buttonleft,mcsb_buttonright); /*scroll*/ var mcsb_containerp=math.abs(math.round(mcsb_container.position().top)); $this.mcustomscrollbar("scrollto",mcsb_containerp,{callback:false}); }else if(mcsb_containerw>mcustomscrollboxw && $this.data("horizontalscroll")){ /*content needs horizontal scrolling*/ mcsb_scrolltools.css("display","block"); var mcsb_draggercontainerw=mcsb_draggercontainer.width(); /*auto adjust scrollbar dragger length analogous to content*/ if($this.data("autodraggerlength")){ var draggerw=math.round(mcustomscrollboxw/mcsb_containerw*mcsb_draggercontainerw), mindraggerw=mcsb_dragger.data("mindraggerwidth"); if(draggerw<=mindraggerw){ /*min dragger height*/ mcsb_dragger.css({"width":mindraggerw}); }else if(draggerw>=mcsb_draggercontainerw-10){ /*max dragger height*/ var mcsb_draggercontainermaxw=mcsb_draggercontainerw-10; mcsb_dragger.css({"width":mcsb_draggercontainermaxw}); }else{ mcsb_dragger.css({"width":draggerw}); } } var mcsb_draggerw=mcsb_dragger.width(), /*calculate and store scroll amount, add scrolling*/ scrollamount=(mcsb_containerw-mcustomscrollboxw)/(mcsb_draggercontainerw-mcsb_draggerw); $this.data("scrollamount",scrollamount).mcustomscrollbar("scrolling",mcustomscrollbox,mcsb_container,mcsb_draggercontainer,mcsb_dragger,mcsb_buttonup,mcsb_buttondown,mcsb_buttonleft,mcsb_buttonright); /*scroll*/ var mcsb_containerp=math.abs(math.round(mcsb_container.position().left)); $this.mcustomscrollbar("scrollto",mcsb_containerp,{callback:false}); }else{ /*content does not need scrolling*/ /*unbind events, reset content position, hide scrollbars, remove classes*/ mcustomscrollbox.unbind("mousewheel focusin"); if($this.data("horizontalscroll")){ mcsb_dragger.add(mcsb_container).css("left",0); }else{ mcsb_dragger.add(mcsb_container).css("top",0); } mcsb_scrolltools.css("display","none"); mcsb_container.addclass("mcs_no_scrollbar"); $this.data({"bindevent_mousewheel":false,"bindevent_focusin":false}); } }, scrolling:function(mcustomscrollbox,mcsb_container,mcsb_draggercontainer,mcsb_dragger,mcsb_buttonup,mcsb_buttondown,mcsb_buttonleft,mcsb_buttonright){ var $this=$(this); /*while scrolling callback*/ $this.mcustomscrollbar("callbacks","whilescrolling"); /*drag scrolling*/ if(!mcsb_dragger.hasclass("ui-draggable")){ /*apply drag function once*/ if($this.data("horizontalscroll")){ var draggableaxis="x"; }else{ var draggableaxis="y"; } mcsb_dragger.draggable({ axis:draggableaxis, containment:"parent", drag:function(event,ui){ $this.mcustomscrollbar("scroll"); mcsb_dragger.addclass("mcsb_dragger_ondrag"); }, stop:function(event,ui){ mcsb_dragger.removeclass("mcsb_dragger_ondrag"); } }); } if(!$this.data("bindevent_scrollbar_click")){ /*bind once*/ mcsb_draggercontainer.bind("click",function(e){ if($this.data("horizontalscroll")){ var mousecoord=(e.pagex-mcsb_draggercontainer.offset().left); if(mousecoord(mcsb_dragger.position().left+mcsb_dragger.width())){ var scrolltopos=mousecoord; if(scrolltopos>=mcsb_draggercontainer.width()-mcsb_dragger.width()){ /*max dragger position is bottom*/ scrolltopos=mcsb_draggercontainer.width()-mcsb_dragger.width(); } mcsb_dragger.css("left",scrolltopos); $this.mcustomscrollbar("scroll"); } }else{ var mousecoord=(e.pagey-mcsb_draggercontainer.offset().top); if(mousecoord(mcsb_dragger.position().top+mcsb_dragger.height())){ var scrolltopos=mousecoord; if(scrolltopos>=mcsb_draggercontainer.height()-mcsb_dragger.height()){ /*max dragger position is bottom*/ scrolltopos=mcsb_draggercontainer.height()-mcsb_dragger.height(); } mcsb_dragger.css("top",scrolltopos); $this.mcustomscrollbar("scroll"); } } }); $this.data({"bindevent_scrollbar_click":true}); } /*mousewheel scrolling*/ if($this.data("mousewheel")){ var mousewheelvel=$this.data("mousewheel"); if($this.data("mousewheel")==="auto"){ mousewheelvel=8; /*default mousewheel velocity*/ /*check for safari browser on mac osx to lower mousewheel velocity*/ var os=navigator.useragent; if(os.indexof("mac")!=-1 && os.indexof("safari")!=-1 && os.indexof("applewebkit")!=-1 && os.indexof("chrome")==-1){ mousewheelvel=1; } } if(!$this.data("bindevent_mousewheel")){ /*bind once*/ mcustomscrollbox.bind("mousewheel",function(event,delta){ event.preventdefault(); var vel=math.abs(delta*mousewheelvel); if($this.data("horizontalscroll")){ if($this.data("mousewheel")==="pixels"){ if(delta<0){ delta=-1; }else{ delta=1; } var scrollto=math.abs(math.round(mcsb_container.position().left))-(delta*$this.data("mousewheelpixels")); $this.mcustomscrollbar("scrollto",scrollto); }else{ var posx=mcsb_dragger.position().left-(delta*vel); mcsb_dragger.css("left",posx); if(mcsb_dragger.position().left<0){ mcsb_dragger.css("left",0); } var mcsb_draggercontainerw=mcsb_draggercontainer.width(), mcsb_draggerw=mcsb_dragger.width(); if(mcsb_dragger.position().left>mcsb_draggercontainerw-mcsb_draggerw){ mcsb_dragger.css("left",mcsb_draggercontainerw-mcsb_draggerw); } $this.mcustomscrollbar("scroll"); } }else{ if($this.data("mousewheel")==="pixels"){ if(delta<0){ delta=-1; }else{ delta=1; } var scrollto=math.abs(math.round(mcsb_container.position().top))-(delta*$this.data("mousewheelpixels")); $this.mcustomscrollbar("scrollto",scrollto); }else{ var posy=mcsb_dragger.position().top-(delta*vel); mcsb_dragger.css("top",posy); if(mcsb_dragger.position().top<0){ mcsb_dragger.css("top",0); } var mcsb_draggercontainerh=mcsb_draggercontainer.height(), mcsb_draggerh=mcsb_dragger.height(); if(mcsb_dragger.position().top>mcsb_draggercontainerh-mcsb_draggerh){ mcsb_dragger.css("top",mcsb_draggercontainerh-mcsb_draggerh); } $this.mcustomscrollbar("scroll"); } } }); $this.data({"bindevent_mousewheel":true}); } } /*buttons scrolling*/ if($this.data("scrollbuttons_enable")){ if($this.data("scrollbuttons_scrolltype")==="pixels"){ /*scroll by pixels*/ var pixelsscrollto; if($.browser.msie && parseint($.browser.version)<9){ /*stupid ie8*/ $this.data("scrollinertia",0); } if($this.data("horizontalscroll")){ mcsb_buttonright.add(mcsb_buttonleft).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mcsb_buttonright_stop,mcsb_buttonleft_stop); $this.data({"bindevent_buttonscontinuous_x":false}); if(!$this.data("bindevent_buttonspixels_x")){ /*bind once*/ /*scroll right*/ mcsb_buttonright.bind("click",function(e){ e.preventdefault(); if(!mcsb_container.is(":animated")){ pixelsscrollto=math.abs(mcsb_container.position().left)+$this.data("scrollbuttons_scrollamount"); $this.mcustomscrollbar("scrollto",pixelsscrollto); } }); /*scroll left*/ mcsb_buttonleft.bind("click",function(e){ e.preventdefault(); if(!mcsb_container.is(":animated")){ pixelsscrollto=math.abs(mcsb_container.position().left)-$this.data("scrollbuttons_scrollamount"); if(mcsb_container.position().left>=-$this.data("scrollbuttons_scrollamount")){ pixelsscrollto="left"; } $this.mcustomscrollbar("scrollto",pixelsscrollto); } }); $this.data({"bindevent_buttonspixels_x":true}); } }else{ mcsb_buttondown.add(mcsb_buttonup).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mcsb_buttonright_stop,mcsb_buttonleft_stop); $this.data({"bindevent_buttonscontinuous_y":false}); if(!$this.data("bindevent_buttonspixels_y")){ /*bind once*/ /*scroll down*/ mcsb_buttondown.bind("click",function(e){ e.preventdefault(); if(!mcsb_container.is(":animated")){ pixelsscrollto=math.abs(mcsb_container.position().top)+$this.data("scrollbuttons_scrollamount"); $this.mcustomscrollbar("scrollto",pixelsscrollto); } }); /*scroll up*/ mcsb_buttonup.bind("click",function(e){ e.preventdefault(); if(!mcsb_container.is(":animated")){ pixelsscrollto=math.abs(mcsb_container.position().top)-$this.data("scrollbuttons_scrollamount"); if(mcsb_container.position().top>=-$this.data("scrollbuttons_scrollamount")){ pixelsscrollto="top"; } $this.mcustomscrollbar("scrollto",pixelsscrollto); } }); $this.data({"bindevent_buttonspixels_y":true}); } } }else{ /*continuous scrolling*/ if($this.data("horizontalscroll")){ mcsb_buttonright.add(mcsb_buttonleft).unbind("click"); $this.data({"bindevent_buttonspixels_x":false}); if(!$this.data("bindevent_buttonscontinuous_x")){ /*bind once*/ /*scroll right*/ mcsb_buttonright.bind("mousedown touchstart onmsgesturestart",function(e){ e.preventdefault(); e.stoppropagation(); $this.data({"mcsb_buttonscrollright":setinterval(function(){ var scrollto=math.round((math.abs(math.round(mcsb_container.position().left))+$this.data("scrollbuttons_scrollspeed"))/$this.data("scrollamount")); $this.mcustomscrollbar("scrollto",scrollto,{movedragger:true}); },30)}); }); var mcsb_buttonright_stop=function(e){ e.preventdefault(); e.stoppropagation(); clearinterval($this.data("mcsb_buttonscrollright")); } mcsb_buttonright.bind("mouseup touchend onmsgestureend mouseout",mcsb_buttonright_stop); /*scroll left*/ mcsb_buttonleft.bind("mousedown touchstart onmsgesturestart",function(e){ e.preventdefault(); e.stoppropagation(); $this.data({"mcsb_buttonscrollleft":setinterval(function(){ var scrollto=math.round((math.abs(math.round(mcsb_container.position().left))-$this.data("scrollbuttons_scrollspeed"))/$this.data("scrollamount")); $this.mcustomscrollbar("scrollto",scrollto,{movedragger:true}); },30)}); }); var mcsb_buttonleft_stop=function(e){ e.preventdefault(); e.stoppropagation(); clearinterval($this.data("mcsb_buttonscrollleft")); } mcsb_buttonleft.bind("mouseup touchend onmsgestureend mouseout",mcsb_buttonleft_stop); $this.data({"bindevent_buttonscontinuous_x":true}); } }else{ mcsb_buttondown.add(mcsb_buttonup).unbind("click"); $this.data({"bindevent_buttonspixels_y":false}); if(!$this.data("bindevent_buttonscontinuous_y")){ /*bind once*/ /*scroll down*/ mcsb_buttondown.bind("mousedown touchstart onmsgesturestart",function(e){ e.preventdefault(); e.stoppropagation(); $this.data({"mcsb_buttonscrolldown":setinterval(function(){ var scrollto=math.round((math.abs(math.round(mcsb_container.position().top))+$this.data("scrollbuttons_scrollspeed"))/$this.data("scrollamount")); $this.mcustomscrollbar("scrollto",scrollto,{movedragger:true}); },30)}); }); var mcsb_buttondown_stop=function(e){ e.preventdefault(); e.stoppropagation(); clearinterval($this.data("mcsb_buttonscrolldown")); } mcsb_buttondown.bind("mouseup touchend onmsgestureend mouseout",mcsb_buttondown_stop); /*scroll up*/ mcsb_buttonup.bind("mousedown touchstart onmsgesturestart",function(e){ e.preventdefault(); e.stoppropagation(); $this.data({"mcsb_buttonscrollup":setinterval(function(){ var scrollto=math.round((math.abs(math.round(mcsb_container.position().top))-$this.data("scrollbuttons_scrollspeed"))/$this.data("scrollamount")); $this.mcustomscrollbar("scrollto",scrollto,{movedragger:true}); },30)}); }); var mcsb_buttonup_stop=function(e){ e.preventdefault(); e.stoppropagation(); clearinterval($this.data("mcsb_buttonscrollup")); } mcsb_buttonup.bind("mouseup touchend onmsgestureend mouseout",mcsb_buttonup_stop); $this.data({"bindevent_buttonscontinuous_y":true}); } } } } /*scrolling on element focus (e.g. via tab key)*/ if($this.data("autoscrollonfocus")){ if(!$this.data("bindevent_focusin")){ /*bind once*/ mcustomscrollbox.bind("focusin",function(){ mcustomscrollbox.scrolltop(0).scrollleft(0); var focusedelem=$(document.activeelement); if(focusedelem.is("input,textarea,select,button,a[tabindex],area,object")){ if($this.data("horizontalscroll")){ var mcsb_containerx=mcsb_container.position().left, focusedelemx=focusedelem.position().left, mcustomscrollboxw=mcustomscrollbox.width(), focusedelemw=focusedelem.outerwidth(); if(mcsb_containerx+focusedelemx>=0 && mcsb_containerx+focusedelemx<=mcustomscrollboxw-focusedelemw){ /*just focus...*/ }else{ /*scroll, then focus*/ var movedragger=focusedelemx/$this.data("scrollamount"); if(movedragger>=mcsb_draggercontainer.width()-mcsb_dragger.width()){ /*max dragger position is bottom*/ movedragger=mcsb_draggercontainer.width()-mcsb_dragger.width(); } mcsb_dragger.css("left",movedragger); $this.mcustomscrollbar("scroll"); } }else{ var mcsb_containery=mcsb_container.position().top, focusedelemy=focusedelem.position().top, mcustomscrollboxh=mcustomscrollbox.height(), focusedelemh=focusedelem.outerheight(); if(mcsb_containery+focusedelemy>=0 && mcsb_containery+focusedelemy<=mcustomscrollboxh-focusedelemh){ /*just focus...*/ }else{ /*scroll, then focus*/ var movedragger=focusedelemy/$this.data("scrollamount"); if(movedragger>=mcsb_draggercontainer.height()-mcsb_dragger.height()){ /*max dragger position is bottom*/ movedragger=mcsb_draggercontainer.height()-mcsb_dragger.height(); } mcsb_dragger.css("top",movedragger); $this.mcustomscrollbar("scroll"); } } } }); $this.data({"bindevent_focusin":true}); } } /*touch events*/ if($(document).data("mcs-is-touch-device")){ /*scrollbar touch-drag*/ if(!$this.data("bindevent_scrollbar_touch")){ /*bind once*/ var mcsb_draggertouchy, mcsb_draggertouchx; mcsb_dragger.bind("touchstart onmsgesturestart",function(e){ e.preventdefault(); e.stoppropagation(); var touch=e.originalevent.touches[0] || e.originalevent.changedtouches[0], elem=$(this), elemoffset=elem.offset(), x=touch.pagex-elemoffset.left, y=touch.pagey-elemoffset.top; if(x0 && y0){ mcsb_draggertouchy=y; mcsb_draggertouchx=x; } }); mcsb_dragger.bind("touchmove onmsgesturechange",function(e){ e.preventdefault(); e.stoppropagation(); var touch=e.originalevent.touches[0] || e.originalevent.changedtouches[0], elem=$(this), elemoffset=elem.offset(), x=touch.pagex-elemoffset.left, y=touch.pagey-elemoffset.top; if($this.data("horizontalscroll")){ $this.mcustomscrollbar("scrollto",(mcsb_dragger.position().left-(mcsb_draggertouchx))+x,{movedragger:true}); }else{ $this.mcustomscrollbar("scrollto",(mcsb_dragger.position().top-(mcsb_draggertouchy))+y,{movedragger:true}); } }); $this.data({"bindevent_scrollbar_touch":true}); } /*content touch-drag*/ if(!$this.data("bindevent_content_touch")){ /*bind once*/ var touch, elem, elemoffset, x, y, mcsb_containertouchy, mcsb_containertouchx; mcsb_container.bind("touchstart onmsgesturestart",function(e){ touch=e.originalevent.touches[0] || e.originalevent.changedtouches[0]; elem=$(this); elemoffset=elem.offset(); x=touch.pagex-elemoffset.left; y=touch.pagey-elemoffset.top; mcsb_containertouchy=y; mcsb_containertouchx=x; }); mcsb_container.bind("touchmove onmsgesturechange",function(e){ e.preventdefault(); e.stoppropagation(); touch=e.originalevent.touches[0] || e.originalevent.changedtouches[0]; elem=$(this).parent(); elemoffset=elem.offset(); x=touch.pagex-elemoffset.left; y=touch.pagey-elemoffset.top; if($this.data("horizontalscroll")){ $this.mcustomscrollbar("scrollto",mcsb_containertouchx-x); }else{ $this.mcustomscrollbar("scrollto",mcsb_containertouchy-y); } }); $this.data({"bindevent_content_touch":true}); } } }, scroll:function(bypasscallbacks){ var $this=$(this), mcsb_dragger=$this.find(".mcsb_dragger"), mcsb_container=$this.find(".mcsb_container"), mcustomscrollbox=$this.find(".mcustomscrollbox"); if($this.data("horizontalscroll")){ var draggerx=mcsb_dragger.position().left, targx=-draggerx*$this.data("scrollamount"), thisx=mcsb_container.position().left, posx=math.round(thisx-targx); }else{ var draggery=mcsb_dragger.position().top, targy=-draggery*$this.data("scrollamount"), thisy=mcsb_container.position().top, posy=math.round(thisy-targy); } if($.browser.webkit){ /*fix webkit zoom and jquery animate*/ var screencsspixelratio=(window.outerwidth-8)/window.innerwidth, iszoomed=(screencsspixelratio<.98 || screencsspixelratio>1.02); } if($this.data("scrollinertia")===0 || iszoomed){ if(!bypasscallbacks){ $this.mcustomscrollbar("callbacks","onscrollstart"); /*user custom callback functions*/ } if($this.data("horizontalscroll")){ mcsb_container.css("left",targx); }else{ mcsb_container.css("top",targy); } if(!bypasscallbacks){ /*user custom callback functions*/ if($this.data("whilescrolling")){ $this.data("whilescrolling_callback").call(); } $this.mcustomscrollbar("callbacks","onscroll"); } $this.data({"mcs_init":false}); }else{ if(!bypasscallbacks){ $this.mcustomscrollbar("callbacks","onscrollstart"); /*user custom callback functions*/ } if($this.data("horizontalscroll")){ mcsb_container.stop().animate({left:"-="+posx},$this.data("scrollinertia"),$this.data("scrolleasing"),function(){ if(!bypasscallbacks){ $this.mcustomscrollbar("callbacks","onscroll"); /*user custom callback functions*/ } $this.data({"mcs_init":false}); }); }else{ mcsb_container.stop().animate({top:"-="+posy},$this.data("scrollinertia"),$this.data("scrolleasing"),function(){ if(!bypasscallbacks){ $this.mcustomscrollbar("callbacks","onscroll"); /*user custom callback functions*/ } $this.data({"mcs_init":false}); }); } } }, scrollto:function(scrollto,options){ var defaults={ movedragger:false, callback:true }, options=$.extend(defaults,options), $this=$(this), scrolltopos, mcustomscrollbox=$this.find(".mcustomscrollbox"), mcsb_container=mcustomscrollbox.children(".mcsb_container"), mcsb_draggercontainer=$this.find(".mcsb_draggercontainer"), mcsb_dragger=mcsb_draggercontainer.children(".mcsb_dragger"), targetpos; if(scrollto || scrollto===0){ if(typeof(scrollto)==="number"){ /*if integer, scroll by number of pixels*/ if(options.movedragger){ /*scroll dragger*/ scrolltopos=scrollto; }else{ /*scroll content by default*/ targetpos=scrollto; scrolltopos=math.round(targetpos/$this.data("scrollamount")); } }else if(typeof(scrollto)==="string"){ /*if string, scroll by element position*/ var target; if(scrollto==="top"){ /*scroll to top*/ target=0; }else if(scrollto==="bottom" && !$this.data("horizontalscroll")){ /*scroll to bottom*/ target=mcsb_container.outerheight()-mcustomscrollbox.height(); }else if(scrollto==="left"){ /*scroll to left*/ target=0; }else if(scrollto==="right" && $this.data("horizontalscroll")){ /*scroll to right*/ target=mcsb_container.outerwidth()-mcustomscrollbox.width(); }else if(scrollto==="first"){ /*scroll to first element position*/ target=$this.find(".mcsb_container").find(":first"); }else if(scrollto==="last"){ /*scroll to last element position*/ target=$this.find(".mcsb_container").find(":last"); }else{ /*scroll to element position*/ target=$this.find(scrollto); } if(target.length===1){ /*if such unique element exists, scroll to it*/ if($this.data("horizontalscroll")){ targetpos=target.position().left; }else{ targetpos=target.position().top; } scrolltopos=math.ceil(targetpos/$this.data("scrollamount")); }else{ scrolltopos=target; } } /*scroll to*/ if(scrolltopos<0){ scrolltopos=0; } if($this.data("horizontalscroll")){ if(scrolltopos>=mcsb_draggercontainer.width()-mcsb_dragger.width()){ /*max dragger position is bottom*/ scrolltopos=mcsb_draggercontainer.width()-mcsb_dragger.width(); } mcsb_dragger.css("left",scrolltopos); }else{ if(scrolltopos>=mcsb_draggercontainer.height()-mcsb_dragger.height()){ /*max dragger position is bottom*/ scrolltopos=mcsb_draggercontainer.height()-mcsb_dragger.height(); } mcsb_dragger.css("top",scrolltopos); } if(options.callback){ $this.mcustomscrollbar("scroll",false); }else{ $this.mcustomscrollbar("scroll",true); } } }, callbacks:function(callback){ var $this=$(this), mcustomscrollbox=$this.find(".mcustomscrollbox"), mcsb_container=$this.find(".mcsb_container"); switch(callback){ /*start scrolling callback*/ case "onscrollstart": if(!mcsb_container.is(":animated")){ $this.data("onscrollstart_callback").call(); } break; /*end scrolling callback*/ case "onscroll": if($this.data("horizontalscroll")){ var mcsb_containerx=math.round(mcsb_container.position().left); if(mcsb_containerx<0 && mcsb_containerx<=mcustomscrollbox.width()-mcsb_container.outerwidth()+$this.data("ontotalscroll_offset")){ $this.data("ontotalscroll_callback").call(); }else if(mcsb_containerx>=-$this.data("ontotalscroll_offset")){ $this.data("ontotalscrollback_callback").call(); }else{ $this.data("onscroll_callback").call(); } }else{ var mcsb_containery=math.round(mcsb_container.position().top); if(mcsb_containery<0 && mcsb_containery<=mcustomscrollbox.height()-mcsb_container.outerheight()+$this.data("ontotalscroll_offset")){ $this.data("ontotalscroll_callback").call(); }else if(mcsb_containery>=-$this.data("ontotalscroll_offset")){ $this.data("ontotalscrollback_callback").call(); }else{ $this.data("onscroll_callback").call(); } } break; /*while scrolling callback*/ case "whilescrolling": if($this.data("whilescrolling_callback") && !$this.data("whilescrolling")){ $this.data({"whilescrolling":setinterval(function(){ if(mcsb_container.is(":animated") && !$this.data("mcs_init")){ $this.data("whilescrolling_callback").call(); } },$this.data("whilescrolling_interval"))}); } break; } }, disable:function(resetscroll){ var $this=$(this), mcustomscrollbox=$this.children(".mcustomscrollbox"), mcsb_container=mcustomscrollbox.children(".mcsb_container"), mcsb_scrolltools=mcustomscrollbox.children(".mcsb_scrolltools"), mcsb_dragger=mcsb_scrolltools.find(".mcsb_dragger"); mcustomscrollbox.unbind("mousewheel focusin"); if(resetscroll){ if($this.data("horizontalscroll")){ mcsb_dragger.add(mcsb_container).css("left",0); }else{ mcsb_dragger.add(mcsb_container).css("top",0); } } mcsb_scrolltools.css("display","none"); mcsb_container.addclass("mcs_no_scrollbar"); $this.data({"bindevent_mousewheel":false,"bindevent_focusin":false}).addclass("mcs_disabled"); }, destroy:function(){ var $this=$(this), content=$this.find(".mcsb_container").html(); $this.find(".mcustomscrollbox").remove(); $this.html(content).removeclass("mcustomscrollbar _mcs_"+$(document).data("mcustomscrollbar-index")).addclass("mcs_destroyed"); } } $.fn.mcustomscrollbar=function(method){ if(methods[method]){ return methods[method].apply(this,array.prototype.slice.call(arguments,1)); }else if(typeof method==="object" || !method){ return methods.init.apply(this,arguments); }else{ $.error("method "+method+" does not exist"); } }; })(jquery); /*ios 6 bug fix ios 6 suffers from a bug that kills timers that are created while a page is scrolling. the following fixes that problem by recreating timers after scrolling finishes (with interval correction).*/ var iosversion=iosversion(); if(iosversion>=6){ (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)); } function iosversion(){ var agent=window.navigator.useragent, start=agent.indexof('os '); if((agent.indexof('iphone')>-1 || agent.indexof('ipad')>-1) && start>-1){ return window.number(agent.substr(start+3,3).replace('_','.')); } return 0; }