/* == malihu jquery custom scrollbars plugin == version: 2.8.2 author: malihu (http://manos.malihu.gr) plugin home: http://manos.malihu.gr/jquery-custom-content-scroller */ /* copyright 2010-2013 manos malihutsakis this program is free software: you can redistribute it and/or modify it under the terms of the gnu lesser general public license as published by the free software foundation, either version 3 of the license, or any later version. this program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. see the gnu lesser general public license for more details. you should have received a copy of the gnu lesser general public license along with this program. if not, see http://www.gnu.org/licenses/lgpl.html. */ (function($){ /*plugin script*/ 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:950, /*scrolling inertia: integer (milliseconds)*/ mousewheel:true, /*mousewheel support: boolean*/ mousewheelpixels:"auto", /*mousewheel pixels amount: integer, "auto"*/ autodraggerlength:true, /*auto-adjust scrollbar dragger length: boolean*/ autohidescrollbar:false, /*auto-hide scrollbar when idle*/ snapamount:null, /* optional element always snaps to a multiple of this number in pixels */ snapoffset:0, /* when snapping, snap with this number in pixels as an offset */ scrollbuttons:{ /*scroll buttons*/ enable:false, /*scroll buttons support: boolean*/ scrolltype:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/ scrollspeed:"auto", /*scroll buttons continuous scrolling speed: integer, "auto"*/ 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*/ normalizemousewheeldelta:false /*normalize mouse-wheel delta (-1/1)*/ }, contenttouchscroll:true, /*scrolling by touch-swipe content: 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)*/ ontotalscrollbackoffset:0, /*scroll begin reached offset: integer (pixels)*/ whilescrolling:function(){} /*user custom callback function on scrolling event*/ }, theme:"light" /*"light", "dark", "light-2", "dark-2", "light-thick", "dark-thick", "light-thin", "dark-thin"*/ }, options=$.extend(true,defaults,options); 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($.support.touch){ 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*/ $this.data({ /*init state*/ "mcs_init":true, /*instance index*/ "mcustomscrollbarindex":$(document).data("mcustomscrollbar-index"), /*option parameters*/ "horizontalscroll":options.horizontalscroll, "scrollinertia":options.scrollinertia, "scrolleasing":"mcseaseout", "mousewheel":options.mousewheel, "mousewheelpixels":options.mousewheelpixels, "autodraggerlength":options.autodraggerlength, "autohidescrollbar":options.autohidescrollbar, "snapamount":options.snapamount, "snapoffset":options.snapoffset, "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, "normalizemousewheeldelta":options.advanced.normalizemousewheeldelta, "contenttouchscroll":options.contenttouchscroll, "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, "ontotalscrollback_offset":options.callbacks.ontotalscrollbackoffset, "whilescrolling_callback":options.callbacks.whilescrolling, /*events binding state*/ "bindevent_scrollbar_drag":false, "bindevent_content_touch":false, "bindevent_scrollbar_click":false, "bindevent_mousewheel":false, "bindevent_buttonscontinuous_y":false, "bindevent_buttonscontinuous_x":false, "bindevent_buttonspixels_y":false, "bindevent_buttonspixels_x":false, "bindevent_focusin":false, "bindevent_autohidescrollbar":false, /*buttons intervals*/ "mcsb_buttonscrollright":false, "mcsb_buttonscrollleft":false, "mcsb_buttonscrolldown":false, "mcsb_buttonscrollup":false }); /*max-width/max-height*/ if(options.horizontalscroll){ if($this.css("max-width")!=="none"){ if(!options.advanced.updateoncontentresize){ /*needs updateoncontentresize*/ options.advanced.updateoncontentresize=true; } } }else{ if($this.css("max-height")!=="none"){ var percentage=false,maxheight=parseint($this.css("max-height")); if($this.css("max-height").indexof("%")>=0){ percentage=maxheight, maxheight=$this.parent().height()*percentage/100; } $this.css("overflow","hidden"); mcustomscrollbox.css("max-height",maxheight); } } $this.mcustomscrollbar("update"); /*window resize fn (for layouts based on percentages)*/ if(options.advanced.updateonbrowserresize){ var mcsb_resizetimeout,currwinwidth=$(window).width(),currwinheight=$(window).height(); $(window).bind("resize."+$this.data("mcustomscrollbarindex"),function(){ if(mcsb_resizetimeout){ cleartimeout(mcsb_resizetimeout); } mcsb_resizetimeout=settimeout(function(){ if(!$this.is(".mcs_disabled") && !$this.is(".mcs_destroyed")){ var winwidth=$(window).width(),winheight=$(window).height(); if(currwinwidth!==winwidth || currwinheight!==winheight){ /*ie8 fix*/ if($this.css("max-height")!=="none" && percentage){ mcustomscrollbox.css("max-height",$this.parent().height()*percentage/100); } $this.mcustomscrollbar("update"); currwinwidth=winwidth; currwinheight=winheight; } } },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(mcsb_container.position().top); $this.mcustomscrollbar("scrollto",mcsb_containerp,{scrollinertia:0,trigger:"internal"}); }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(mcsb_container.position().left); $this.mcustomscrollbar("scrollto",mcsb_containerp,{scrollinertia:0,trigger:"internal"}); }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); /*scrollbar drag scrolling*/ if(!$this.data("bindevent_scrollbar_drag")){ var mcsb_draggerdragy,mcsb_draggerdragx; if($.support.mspointer){ /*mspointer*/ mcsb_dragger.bind("mspointerdown",function(e){ e.preventdefault(); $this.data({"on_drag":true}); mcsb_dragger.addclass("mcsb_dragger_ondrag"); var elem=$(this), elemoffset=elem.offset(), x=e.originalevent.pagex-elemoffset.left, y=e.originalevent.pagey-elemoffset.top; if(x0 && y0){ mcsb_draggerdragy=y; mcsb_draggerdragx=x; } }); $(document).bind("mspointermove."+$this.data("mcustomscrollbarindex"),function(e){ e.preventdefault(); if($this.data("on_drag")){ var elem=mcsb_dragger, elemoffset=elem.offset(), x=e.originalevent.pagex-elemoffset.left, y=e.originalevent.pagey-elemoffset.top; scrollbardrag(mcsb_draggerdragy,mcsb_draggerdragx,y,x); } }).bind("mspointerup."+$this.data("mcustomscrollbarindex"),function(e){ $this.data({"on_drag":false}); mcsb_dragger.removeclass("mcsb_dragger_ondrag"); }); }else{ /*mouse/touch*/ mcsb_dragger.bind("mousedown touchstart",function(e){ e.preventdefault(); e.stopimmediatepropagation(); var elem=$(this),elemoffset=elem.offset(),x,y; if(e.type==="touchstart"){ var touch=e.originalevent.touches[0] || e.originalevent.changedtouches[0]; x=touch.pagex-elemoffset.left; y=touch.pagey-elemoffset.top; }else{ $this.data({"on_drag":true}); mcsb_dragger.addclass("mcsb_dragger_ondrag"); x=e.pagex-elemoffset.left; y=e.pagey-elemoffset.top; } if(x0 && y0){ mcsb_draggerdragy=y; mcsb_draggerdragx=x; } }).bind("touchmove",function(e){ e.preventdefault(); e.stopimmediatepropagation(); 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; scrollbardrag(mcsb_draggerdragy,mcsb_draggerdragx,y,x); }); $(document).bind("mousemove."+$this.data("mcustomscrollbarindex"),function(e){ if($this.data("on_drag")){ var elem=mcsb_dragger, elemoffset=elem.offset(), x=e.pagex-elemoffset.left, y=e.pagey-elemoffset.top; scrollbardrag(mcsb_draggerdragy,mcsb_draggerdragx,y,x); } }).bind("mouseup."+$this.data("mcustomscrollbarindex"),function(e){ $this.data({"on_drag":false}); mcsb_dragger.removeclass("mcsb_dragger_ondrag"); }); } $this.data({"bindevent_scrollbar_drag":true}); } function scrollbardrag(mcsb_draggerdragy,mcsb_draggerdragx,y,x){ if($this.data("horizontalscroll")){ $this.mcustomscrollbar("scrollto",(mcsb_dragger.position().left-(mcsb_draggerdragx))+x,{movedragger:true,trigger:"internal"}); }else{ $this.mcustomscrollbar("scrollto",(mcsb_dragger.position().top-(mcsb_draggerdragy))+y,{movedragger:true,trigger:"internal"}); } } /*content touch-drag*/ if($.support.touch && $this.data("contenttouchscroll")){ if(!$this.data("bindevent_content_touch")){ var touch, elem,elemoffset,y,x,mcsb_containertouchy,mcsb_containertouchx; mcsb_container.bind("touchstart",function(e){ e.stopimmediatepropagation(); 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",function(e){ e.preventdefault(); e.stopimmediatepropagation(); 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,{trigger:"internal"}); }else{ $this.mcustomscrollbar("scrollto",mcsb_containertouchy-y,{trigger:"internal"}); } }); } } /*dragger rail click scrolling*/ if(!$this.data("bindevent_scrollbar_click")){ mcsb_draggercontainer.bind("click",function(e){ var scrolltopos=(e.pagey-mcsb_draggercontainer.offset().top)*$this.data("scrollamount"),target=$(e.target); if($this.data("horizontalscroll")){ scrolltopos=(e.pagex-mcsb_draggercontainer.offset().left)*$this.data("scrollamount"); } if(target.hasclass("mcsb_draggercontainer") || target.hasclass("mcsb_draggerrail")){ $this.mcustomscrollbar("scrollto",scrolltopos,{trigger:"internal",scrolleasing:"draggerrailease"}); } }); $this.data({"bindevent_scrollbar_click":true}); } /*mousewheel scrolling*/ if($this.data("mousewheel")){ if(!$this.data("bindevent_mousewheel")){ mcustomscrollbox.bind("mousewheel",function(e,delta){ var scrollto,mousewheelpixels=$this.data("mousewheelpixels"),abspos=math.abs(mcsb_container.position().top), draggerpos=mcsb_dragger.position().top,limit=mcsb_draggercontainer.height()-mcsb_dragger.height(); if($this.data("normalizemousewheeldelta")){ if(delta<0){delta=-1;}else{delta=1;} } if(mousewheelpixels==="auto"){ mousewheelpixels=100+math.round($this.data("scrollamount")/2); } if($this.data("horizontalscroll")){ draggerpos=mcsb_dragger.position().left; limit=mcsb_draggercontainer.width()-mcsb_dragger.width(); abspos=math.abs(mcsb_container.position().left); } if((delta>0 && draggerpos!==0) || (delta<0 && draggerpos!==limit)){e.preventdefault(); e.stopimmediatepropagation();} scrollto=abspos-(delta*mousewheelpixels); $this.mcustomscrollbar("scrollto",scrollto,{trigger:"internal"}); }); $this.data({"bindevent_mousewheel":true}); } } /*buttons scrolling*/ if($this.data("scrollbuttons_enable")){ if($this.data("scrollbuttons_scrolltype")==="pixels"){ /*scroll by pixels*/ if($this.data("horizontalscroll")){ mcsb_buttonright.add(mcsb_buttonleft).unbind("mousedown touchstart mspointerdown mouseup mspointerup mouseout mspointerout touchend",mcsb_buttonright_stop,mcsb_buttonleft_stop); $this.data({"bindevent_buttonscontinuous_x":false}); if(!$this.data("bindevent_buttonspixels_x")){ /*scroll right*/ mcsb_buttonright.bind("click",function(e){ e.preventdefault(); pixelsscrollto(math.abs(mcsb_container.position().left)+$this.data("scrollbuttons_scrollamount")); }); /*scroll left*/ mcsb_buttonleft.bind("click",function(e){ e.preventdefault(); pixelsscrollto(math.abs(mcsb_container.position().left)-$this.data("scrollbuttons_scrollamount")); }); $this.data({"bindevent_buttonspixels_x":true}); } }else{ mcsb_buttondown.add(mcsb_buttonup).unbind("mousedown touchstart mspointerdown mouseup mspointerup mouseout mspointerout touchend",mcsb_buttonright_stop,mcsb_buttonleft_stop); $this.data({"bindevent_buttonscontinuous_y":false}); if(!$this.data("bindevent_buttonspixels_y")){ /*scroll down*/ mcsb_buttondown.bind("click",function(e){ e.preventdefault(); pixelsscrollto(math.abs(mcsb_container.position().top)+$this.data("scrollbuttons_scrollamount")); }); /*scroll up*/ mcsb_buttonup.bind("click",function(e){ e.preventdefault(); pixelsscrollto(math.abs(mcsb_container.position().top)-$this.data("scrollbuttons_scrollamount")); }); $this.data({"bindevent_buttonspixels_y":true}); } } function pixelsscrollto(to){ if(!mcsb_dragger.data("preventaction")){ mcsb_dragger.data("preventaction",true); $this.mcustomscrollbar("scrollto",to,{trigger:"internal"}); } } }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")){ /*scroll right*/ mcsb_buttonright.bind("mousedown touchstart mspointerdown",function(e){ e.preventdefault(); var scrollbuttonsspeed=scrollbuttonsspeed(); $this.data({"mcsb_buttonscrollright":setinterval(function(){ $this.mcustomscrollbar("scrollto",math.abs(mcsb_container.position().left)+scrollbuttonsspeed,{trigger:"internal",scrolleasing:"easeoutcirc"}); },17)}); }); var mcsb_buttonright_stop=function(e){ e.preventdefault(); clearinterval($this.data("mcsb_buttonscrollright")); } mcsb_buttonright.bind("mouseup touchend mspointerup mouseout mspointerout",mcsb_buttonright_stop); /*scroll left*/ mcsb_buttonleft.bind("mousedown touchstart mspointerdown",function(e){ e.preventdefault(); var scrollbuttonsspeed=scrollbuttonsspeed(); $this.data({"mcsb_buttonscrollleft":setinterval(function(){ $this.mcustomscrollbar("scrollto",math.abs(mcsb_container.position().left)-scrollbuttonsspeed,{trigger:"internal",scrolleasing:"easeoutcirc"}); },17)}); }); var mcsb_buttonleft_stop=function(e){ e.preventdefault(); clearinterval($this.data("mcsb_buttonscrollleft")); } mcsb_buttonleft.bind("mouseup touchend mspointerup mouseout mspointerout",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")){ /*scroll down*/ mcsb_buttondown.bind("mousedown touchstart mspointerdown",function(e){ e.preventdefault(); var scrollbuttonsspeed=scrollbuttonsspeed(); $this.data({"mcsb_buttonscrolldown":setinterval(function(){ $this.mcustomscrollbar("scrollto",math.abs(mcsb_container.position().top)+scrollbuttonsspeed,{trigger:"internal",scrolleasing:"easeoutcirc"}); },17)}); }); var mcsb_buttondown_stop=function(e){ e.preventdefault(); clearinterval($this.data("mcsb_buttonscrolldown")); } mcsb_buttondown.bind("mouseup touchend mspointerup mouseout mspointerout",mcsb_buttondown_stop); /*scroll up*/ mcsb_buttonup.bind("mousedown touchstart mspointerdown",function(e){ e.preventdefault(); var scrollbuttonsspeed=scrollbuttonsspeed(); $this.data({"mcsb_buttonscrollup":setinterval(function(){ $this.mcustomscrollbar("scrollto",math.abs(mcsb_container.position().top)-scrollbuttonsspeed,{trigger:"internal",scrolleasing:"easeoutcirc"}); },17)}); }); var mcsb_buttonup_stop=function(e){ e.preventdefault(); clearinterval($this.data("mcsb_buttonscrollup")); } mcsb_buttonup.bind("mouseup touchend mspointerup mouseout mspointerout",mcsb_buttonup_stop); $this.data({"bindevent_buttonscontinuous_y":true}); } } function scrollbuttonsspeed(){ var speed=$this.data("scrollbuttons_scrollspeed"); if($this.data("scrollbuttons_scrollspeed")==="auto"){ speed=math.round(($this.data("scrollinertia")+100)/40); } return speed; } } } /*scrolling on element focus (e.g. via tab key)*/ if($this.data("autoscrollonfocus")){ if(!$this.data("bindevent_focusin")){ mcustomscrollbox.bind("focusin",function(){ mcustomscrollbox.scrolltop(0).scrollleft(0); var focusedelem=$(document.activeelement); if(focusedelem.is("input,textarea,select,button,a[tabindex],area,object")){ var mcsb_containerpos=mcsb_container.position().top, focusedelempos=focusedelem.position().top, visiblelimit=mcustomscrollbox.height()-focusedelem.outerheight(); if($this.data("horizontalscroll")){ mcsb_containerpos=mcsb_container.position().left; focusedelempos=focusedelem.position().left; visiblelimit=mcustomscrollbox.width()-focusedelem.outerwidth(); } if(mcsb_containerpos+focusedelempos<0 || mcsb_containerpos+focusedelempos>visiblelimit){ $this.mcustomscrollbar("scrollto",focusedelempos,{trigger:"internal"}); } } }); $this.data({"bindevent_focusin":true}); } } /*auto-hide scrollbar*/ if($this.data("autohidescrollbar")){ if(!$this.data("bindevent_autohidescrollbar")){ mcustomscrollbox.bind("mouseenter",function(e){ mcustomscrollbox.addclass("mcs-mouse-over"); functions.showscrollbar.call(mcustomscrollbox.children(".mcsb_scrolltools")); }).bind("mouseleave touchend",function(e){ mcustomscrollbox.removeclass("mcs-mouse-over"); if(e.type==="mouseleave"){functions.hidescrollbar.call(mcustomscrollbox.children(".mcsb_scrolltools"));} }); $this.data({"bindevent_autohidescrollbar":true}); } } }, scrollto:function(scrollto,options){ var $this=$(this), defaults={ movedragger:false, trigger:"external", callbacks:true, scrollinertia:$this.data("scrollinertia"), scrolleasing:$this.data("scrolleasing") }, options=$.extend(defaults,options), draggerscrollto, mcustomscrollbox=$this.children(".mcustomscrollbox"), mcsb_container=mcustomscrollbox.children(".mcsb_container"), mcsb_scrolltools=mcustomscrollbox.children(".mcsb_scrolltools"), mcsb_draggercontainer=mcsb_scrolltools.children(".mcsb_draggercontainer"), mcsb_dragger=mcsb_draggercontainer.children(".mcsb_dragger"), contentspeed=draggerspeed=options.scrollinertia, scrollbeginning,scrollbeginningoffset,totalscroll,totalscrolloffset; if(!mcsb_container.hasclass("mcs_no_scrollbar")){ $this.data({"mcs_trigger":options.trigger}); if($this.data("mcs_init")){options.callbacks=false;} if(scrollto || scrollto===0){ if(typeof(scrollto)==="number"){ /*if integer, scroll by number of pixels*/ if(options.movedragger){ /*scroll dragger*/ draggerscrollto=scrollto; if($this.data("horizontalscroll")){ scrollto=mcsb_dragger.position().left*$this.data("scrollamount"); }else{ scrollto=mcsb_dragger.position().top*$this.data("scrollamount"); } draggerspeed=0; }else{ /*scroll content by default*/ draggerscrollto=scrollto/$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")){ scrollto=target.position().left; }else{ scrollto=target.position().top; } draggerscrollto=scrollto/$this.data("scrollamount"); }else{ draggerscrollto=scrollto=target; } } /*scroll to*/ if($this.data("horizontalscroll")){ if($this.data("ontotalscrollback_offset")){ /*scroll beginning offset*/ scrollbeginningoffset=-$this.data("ontotalscrollback_offset"); } if($this.data("ontotalscroll_offset")){ /*total scroll offset*/ totalscrolloffset=mcustomscrollbox.width()-mcsb_container.outerwidth()+$this.data("ontotalscroll_offset"); } if(draggerscrollto<0){ /*scroll start position*/ draggerscrollto=scrollto=0; clearinterval($this.data("mcsb_buttonscrollleft")); if(!scrollbeginningoffset){scrollbeginning=true;} }else if(draggerscrollto>=mcsb_draggercontainer.width()-mcsb_dragger.width()){ /*scroll end position*/ draggerscrollto=mcsb_draggercontainer.width()-mcsb_dragger.width(); scrollto=mcustomscrollbox.width()-mcsb_container.outerwidth(); clearinterval($this.data("mcsb_buttonscrollright")); if(!totalscrolloffset){totalscroll=true;} }else{scrollto=-scrollto;} var snapamount = $this.data("snapamount"); if (snapamount) { scrollto = math.round(scrollto / snapamount) * snapamount - $this.data("snapoffset"); } /*scrolling animation*/ functions.mtweenaxis.call(this,mcsb_dragger[0],"left",math.round(draggerscrollto),draggerspeed,options.scrolleasing); functions.mtweenaxis.call(this,mcsb_container[0],"left",math.round(scrollto),contentspeed,options.scrolleasing,{ onstart:function(){ if(options.callbacks && !$this.data("mcs_tweenrunning")){callbacks("onscrollstart");} if($this.data("autohidescrollbar")){functions.showscrollbar.call(mcsb_scrolltools);} }, onupdate:function(){ if(options.callbacks){callbacks("whilescrolling");} }, oncomplete:function(){ if(options.callbacks){ callbacks("onscroll"); if(scrollbeginning || (scrollbeginningoffset && mcsb_container.position().left>=scrollbeginningoffset)){callbacks("ontotalscrollback");} if(totalscroll || (totalscrolloffset && mcsb_container.position().left<=totalscrolloffset)){callbacks("ontotalscroll");} } mcsb_dragger.data("preventaction",false); $this.data("mcs_tweenrunning",false); if($this.data("autohidescrollbar")){if(!mcustomscrollbox.hasclass("mcs-mouse-over")){functions.hidescrollbar.call(mcsb_scrolltools);}} } }); }else{ if($this.data("ontotalscrollback_offset")){ /*scroll beginning offset*/ scrollbeginningoffset=-$this.data("ontotalscrollback_offset"); } if($this.data("ontotalscroll_offset")){ /*total scroll offset*/ totalscrolloffset=mcustomscrollbox.height()-mcsb_container.outerheight()+$this.data("ontotalscroll_offset"); } if(draggerscrollto<0){ /*scroll start position*/ draggerscrollto=scrollto=0; clearinterval($this.data("mcsb_buttonscrollup")); if(!scrollbeginningoffset){scrollbeginning=true;} }else if(draggerscrollto>=mcsb_draggercontainer.height()-mcsb_dragger.height()){ /*scroll end position*/ draggerscrollto=mcsb_draggercontainer.height()-mcsb_dragger.height(); scrollto=mcustomscrollbox.height()-mcsb_container.outerheight(); clearinterval($this.data("mcsb_buttonscrolldown")); if(!totalscrolloffset){totalscroll=true;} }else{scrollto=-scrollto;} var snapamount = $this.data("snapamount"); if (snapamount) { scrollto = math.round(scrollto / snapamount) * snapamount - $this.data("snapoffset"); } /*scrolling animation*/ functions.mtweenaxis.call(this,mcsb_dragger[0],"top",math.round(draggerscrollto),draggerspeed,options.scrolleasing); functions.mtweenaxis.call(this,mcsb_container[0],"top",math.round(scrollto),contentspeed,options.scrolleasing,{ onstart:function(){ if(options.callbacks && !$this.data("mcs_tweenrunning")){callbacks("onscrollstart");} if($this.data("autohidescrollbar")){functions.showscrollbar.call(mcsb_scrolltools);} }, onupdate:function(){ if(options.callbacks){callbacks("whilescrolling");} }, oncomplete:function(){ if(options.callbacks){ callbacks("onscroll"); if(scrollbeginning || (scrollbeginningoffset && mcsb_container.position().top>=scrollbeginningoffset)){callbacks("ontotalscrollback");} if(totalscroll || (totalscrolloffset && mcsb_container.position().top<=totalscrolloffset)){callbacks("ontotalscroll");} } mcsb_dragger.data("preventaction",false); $this.data("mcs_tweenrunning",false); if($this.data("autohidescrollbar")){if(!mcustomscrollbox.hasclass("mcs-mouse-over")){functions.hidescrollbar.call(mcsb_scrolltools);}} } }); } if($this.data("mcs_init")){$this.data({"mcs_init":false});} } } /*callbacks*/ function callbacks(cb){ this.mcs={ top:mcsb_container.position().top,left:mcsb_container.position().left, draggertop:mcsb_dragger.position().top,draggerleft:mcsb_dragger.position().left, toppct:math.round((100*math.abs(mcsb_container.position().top))/math.abs(mcsb_container.outerheight()-mcustomscrollbox.height())), leftpct:math.round((100*math.abs(mcsb_container.position().left))/math.abs(mcsb_container.outerwidth()-mcustomscrollbox.width())) }; switch(cb){ /*start scrolling callback*/ case "onscrollstart": $this.data("mcs_tweenrunning",true).data("onscrollstart_callback").call($this,this.mcs); break; case "whilescrolling": $this.data("whilescrolling_callback").call($this,this.mcs); break; case "onscroll": $this.data("onscroll_callback").call($this,this.mcs); break; case "ontotalscrollback": $this.data("ontotalscrollback_callback").call($this,this.mcs); break; case "ontotalscroll": $this.data("ontotalscroll_callback").call($this,this.mcs); break; } } }, stop:function(){ var $this=$(this), mcsb_container=$this.children().children(".mcsb_container"), mcsb_dragger=$this.children().children().children().children(".mcsb_dragger"); functions.mtweenaxisstop.call(this,mcsb_container[0]); functions.mtweenaxisstop.call(this,mcsb_dragger[0]); }, 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.children().children(".mcsb_dragger"); mcustomscrollbox.unbind("mousewheel focusin mouseenter mouseleave touchend"); mcsb_container.unbind("touchstart touchmove") 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,"bindevent_content_touch":false,"bindevent_autohidescrollbar":false}).addclass("mcs_disabled"); }, destroy:function(){ var $this=$(this); $this.removeclass("mcustomscrollbar _mcs_"+$this.data("mcustomscrollbarindex")).addclass("mcs_destroyed").children().children(".mcsb_container").unwrap().children().unwrap().siblings(".mcsb_scrolltools").remove(); $(document).unbind("mousemove."+$this.data("mcustomscrollbarindex")+" mouseup."+$this.data("mcustomscrollbarindex")+" mspointermove."+$this.data("mcustomscrollbarindex")+" mspointerup."+$this.data("mcustomscrollbarindex")); $(window).unbind("resize."+$this.data("mcustomscrollbarindex")); } }, functions={ /*hide/show scrollbar*/ showscrollbar:function(){ this.stop().animate({opacity:1},"fast"); }, hidescrollbar:function(){ this.stop().animate({opacity:0},"fast"); }, /*js animation tween*/ mtweenaxis:function(el,prop,to,duration,easing,callbacks){ var callbacks=callbacks || {}, onstart=callbacks.onstart || function(){},onupdate=callbacks.onupdate || function(){},oncomplete=callbacks.oncomplete || function(){}; var starttime=_gettime(),_delay,progress=0,from=el.offsettop,elstyle=el.style; if(prop==="left"){from=el.offsetleft;} var diff=to-from; _canceltween(); _starttween(); function _gettime(){ if(window.performance && window.performance.now){ return window.performance.now(); }else{ if(window.performance && window.performance.webkitnow){ return window.performance.webkitnow(); }else{ if(date.now){return date.now();}else{return new date().gettime();} } } } function _step(){ if(!progress){onstart.call();} progress=_gettime()-starttime; _tween(); if(progress>=el._time){ el._time=(progress>el._time) ? progress+_delay-(progress- el._time) : progress+_delay-1; if(el._time0){ el.currval=_ease(el._time,from,diff,duration,easing); elstyle[prop]=math.round(el.currval)+"px"; }else{ elstyle[prop]=to+"px"; } onupdate.call(); } function _starttween(){ _delay=1000/60; el._time=progress+_delay; _request=(!window.requestanimationframe) ? function(f){_tween(); return settimeout(f,0.01);} : window.requestanimationframe; el._id=_request(_step); } function _canceltween(){ if(el._id==null){return;} if(!window.requestanimationframe){cleartimeout(el._id); }else{window.cancelanimationframe(el._id);} el._id=null; } function _ease(t,b,c,d,type){ switch(type){ case "linear": return c*t/d + b; break; case "easeoutquad": t /= d; return -c * t*(t-2) + b; break; case "easeinoutquad": t /= d/2; if (t < 1) return c/2*t*t + b; t--; return -c/2 * (t*(t-2) - 1) + b; break; case "easeoutcubic": t /= d; t--; return c*(t*t*t + 1) + b; break; case "easeoutquart": t /= d; t--; return -c * (t*t*t*t - 1) + b; break; case "easeoutquint": t /= d; t--; return c*(t*t*t*t*t + 1) + b; break; case "easeoutcirc": t /= d; t--; return c * math.sqrt(1 - t*t) + b; break; case "easeoutsine": return c * math.sin(t/d * (math.pi/2)) + b; break; case "easeoutexpo": return c * ( -math.pow( 2, -10 * t/d ) + 1 ) + b; break; case "mcseaseout": var ts=(t/=d)*t,tc=ts*t; return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t); break; case "draggerrailease": t /= d/2; if (t < 1) return c/2*t*t*t + b; t -= 2; return c/2*(t*t*t + 2) + b; break; } } }, /*stop js animation tweens*/ mtweenaxisstop:function(el){ if(el._id==null){return;} if(!window.requestanimationframe){cleartimeout(el._id); }else{window.cancelanimationframe(el._id);} el._id=null; }, /*detect requestanimationframe and polyfill*/ rafpolyfill:function(){ var pfx=["ms","moz","webkit","o"],i=pfx.length; while(--i > -1 && !window.requestanimationframe){ window.requestanimationframe=window[pfx[i]+"requestanimationframe"]; window.cancelanimationframe=window[pfx[i]+"cancelanimationframe"] || window[pfx[i]+"cancelrequestanimationframe"]; } } } /*detect features*/ functions.rafpolyfill.call(); /*requestanimationframe*/ $.support.touch=!!('ontouchstart' in window); /*touch*/ $.support.mspointer=window.navigator.mspointerenabled; /*mspointer support*/ /*plugin dependencies*/ var _dlp=("https:"==document.location.protocol) ? "https:" : "http:"; $.event.special.mousewheel || document.write('