/*
== 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._time