Wednesday, January 11, 2012

jquery custom content scroller

Custom scrollbar plugin utilizing jquery UI that’s fully customizable with CSS. It features vertical/horizontal scrolling, mouse-wheel support (via Brandon Aaron jquery mouse-wheel plugin), scroll easing and adjustable scrollbar height/width.






DEMO | DOWNLOAD


How to use it

In order to implement the plugin, you first need to insert inside the head tag of your document the jquery.min.js and jquery-ui.min.js (both loaded from Google), the jquery.easing.1.3.js (the plugin that handles animation easing), jquery.mousewheel.min.js (to support mouse-wheel functionality) and the jquery.mCustomScrollbar.css which is the file where you can style your content and scrollbars.
<link href="jquery.mCustomScrollbar.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
<script src="jquery.easing.1.3.js" type="text/javascript"></script>
<script src="jquery.mousewheel.min.js" type="text/javascript"></script>

Next you’ll need to insert the markup of the content blocks you want to have custom scrollbars inside the body tag. The structure of the markup is exactly the same for every content block except the first div which should have a unique id (in this example: mcs_container).
<div id="mcs_container">
<div class="customScrollBox">
<div class="container">
<div class="content">
<p>Your long content goes here...</p></div>
</div>
<div class="dragger_container">
<div class="dragger"></div>
</div>
</div>
</div>

Keep the markup structure exactly as shown above, placing your content inside the div that has the class name content. In order to have multiple content blocks with custom scrollbars on a single document, you use the exact same markup with a unique id for each block (e.g. mcs_container, mcs2_container, mcs3_container etc.).

The markup for horizontal scrollers needs an additional div with class name horWrapper that wraps the .container div. This is necessary in order to set the total width of contents automatically, without the need to insert it by hand in css or make complicated calculations with javascript.
<div id="mcs_container">
<div class="customScrollBox">
<div class="horWrapper">
<div class="container">
<div class="content">
<p>Your long content goes here...</p></div>
</div>
<div class="dragger_container">
<div class="dragger"></div>
</div>
</div>
</div>
</div>

To add the additional scrollbar buttons, you need to insert two additional anchor tags inside mcs_container div, with class names scrollUpBtn and scrollDownBtn:
<div id="mcs_container">
<div class="customScrollBox">
<div class="container">
<div class="content">
<p>Your long content goes here...</p></div>
</div>
<div class="dragger_container"><div class="dragger"></div></div>
</div>
<!-- scroll buttons -->
<a class="scrollUpBtn" href="#"></a> <a class="scrollDownBtn" href="#"></a>
</div>
</div></div>

An extra feature suggested and provided by isHristov is to add a few lines of CSS right after your content markup, in order to help users that have javascript disabled scroll the content:
<noscript>
    <style type="text/css">
        #mcs_container .customScrollBox{overflow:auto;}
        #mcs_container .dragger_container{display:none;}
    </style>
</noscript>

The final step is to include the actual custom scrollbar plugin (jquery.mCustomScrollbar.js) and the function that calls and configures the scrollbar(s) at the end of your document, just before the closing body tag.
<script>
$(window).load(function() {
    $("#mcs_container").mCustomScrollbar("vertical",400,"easeOutCirc",1.05,"auto","yes","yes",10);
});
</script>
<script src="jquery.mCustomScrollbar.js" type="text/javascript"></script>

You can configure each content block scrollbar by setting the parameters of the function call:

    The scroll type (“vertical” or “horizontal”)
    The scroll easing amount (e.g. 400 for normal easing, 0 for no easing etc.)
    The scroll easing type
    The extra bottom scrolling space (applies to vertical scroll type only)
    Set the scrollbar height/width adjustment (“auto” for adjustable scrollbar height/width analogous to content length or “fixed” for fixed dimensions)
    Set mouse-wheel support (“yes” or “no”)
    Scrolling via buttons support (“yes” or “no”)
    Buttons scrolling speed (an integer between 1 and 20, with 1 indicating the slowest scroll speed)

Multiple scrollers

To set multiple content blocks with custom scrollbars on a single page, give them a unique id (keeping the exact markup) and add a function call for each one. For example:
<script>
$(window).load(function() {
    $("#mcs_container").mCustomScrollbar("vertical",400,"easeOutCirc",1.05,"auto","yes","yes",10);
    $("#mcs2_container").mCustomScrollbar("vertical",0,"easeOutCirc",1.05,"fixed","yes","no",0);
    $("#mcs3_container").mCustomScrollbar("vertical",900,"easeOutCirc",1.25,"auto","no","no",0);
});
</script>

You can style each scroller separately in jquery.mCustomScrollbar.css, since styles are assigned only to the element with the original id (see the .css file inside the jquery_custom_scroller.zip).

Scrolling long content

There’s a bug in jquery.min.js that resets to 0, an animate value greater than 9999 pixels. This bug will affect the scrollbar if content width or height is equal or greater than 10000 pixels, resulting a scrolling jerk. This annoying bug is going to be fixed on a future release of the library. Until then, we need to come up with a temporary solution and since editing jquery.min.js is not the best of practices, we’ll overwrite the jquery function containing the buggy code ;)
Insert the following code below the window load function:
<script>
/* function to fix the -10000 pixel limit of jquery.animate */
$.fx.prototype.cur = function(){
    if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
      return this.elem[ this.prop ];
    }
    var r = parseFloat( jQuery.css( this.elem, this.prop ) );
    return typeof r == 'undefined' ? 0 : r;
}
</script>

Dynamically loaded content

To load new content dynamically inside scroller(s) (via .load(), ajax requests etc.), you need to call (or re-call) mCustomScrollbar function after new content is loaded. For example:
$("#mcs_container .content").load("new.html", function(){
$("#mcs_container").mCustomScrollbar("vertical",400,"easeOutCirc",1.05,"auto","yes","yes",10);
});

When you have multiple content scrollers on a single page that load new content dynamically, it’s better to create another function that calls all scrollers and call it on window.load as well as each time new content is loaded. The demo includes this functionality, so you can check and grab the code.

Hiding content scrollers

If you want to have the scroller initially hidden, you need to hide it after calling the mCustomScrollbar function. This is important, in order for the script to calculate content width or height correctly.

Mousewheel scrolling with Safari on mac OS

Mousewheel scrolling with Safari browser on OSX might be extremely fast thus a bit unusable (blame the vendor!). I have uploaded a modified jquery.mCustomScrollbar.js at http://manos.malihu.gr/tuts/jquery_custom_scroller_js_osxsafari.zip that checks for mac OS and Safari browser to lower mousewheel delta. I haven’t implement the modification in the original plugin cause I don’t really fancy coding for specific operating systems or browsers.

If you need assistance with the script, please make sure you read the comments section (at the moment there are over 500 comments), as many users have answered questions and posted helpful bits of code ;)

Feel free to use the plugin wherever and however you like. Enjoy :)

No comments:

Post a Comment