Vertical scrollbar plugin using jQuery UI slider
This plugin wraps up a number of the variants of my jQuery vertical scrollbar. Specifically this plugin supports:
- Multiple sliders on one page
- Scrolling with a mousewheel
- The use of images for scrollbar handles
- The size of the scrolled content changing after load (through AJAX for example)
- Customisation via css
I’ve tested this in FF7, IE6, IE7, IE8, Chrome, Safari 5 and Opera 11, all on Windows 7, using jQuery 1.7.1 and jQuery UI 1.8.14.
Setup
This plugin requires jQuery and jQuery UI, so you need to load these and the plugin into in your head, plus the css file. Optionally, you can load Brendan Aaron’s mousewheel plugin as well. Then, assuming you have stored the javascript files in a folder in your root file called javascript, and the css file in a folder in your root file called css, then you should have something like this:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script> <script type="text/javascript" src="/javascript/jquery.sbscroller.js"></script> <script type="text/javascript" src="/javascript/jquery.mousewheel.min.3.0.6.js"></script> <link rel="stylesheet" href="/css/jquery.sbscroller.css" />
The plugin will add a scrollbar to a selected element which has a fixed height and content which exceeds that height. The scrollbar will be placed on the right hand side of the scrolled element using position:absolute
. At the moment this means the scrollbar must be within the parent scrolling element, as I thought this might be more convenient. If anyone is interested it would be possible to add an option to position the scrollbar outside the scrolling element, let me know…
Configuration
All you need for the basic scrollbar is this, placed before the closing </body>
tag – where #myelement
is replaced by your element selector, obviously:
<script type="text/javascript"> $('#myelement').sbscroller(); </script>
Options
To set an option, the name, followed by a colon, followed by the required value as shown below, all wrapped in curly brackets {}, needs to be entered in the round brackets after sbscroller. Separate multiple settings with a comma. See below for some examples. Different scrollers on the same page may be set up with different options.
Option | Description | Example values | Default value |
---|---|---|---|
handleImage | A string setting the path of the image to be used as a background-image on the slider handle, which will be set to repeat-y . |
‘/images/handleimage.jpg’ | false |
handleTopImage | A string setting the path of the image to be added to the slider handle, and positioned at the top of the handle. | ‘/images/handletop.jpg’ | false |
handleBottomImage | A string setting the path of the image to be added to the slider handle, and positioned at the bottom of the handle. | ‘/images/handlebottom.jpg’ | false |
handleGripImage | A string setting the path of the image to be added to the slider handle, and positioned at the vertical centre of the handle. | ‘/images/handlegrip.jpg’ | false |
autohide | A Boolean setting the scrollbar to dispay only when the scrolling element is hovered. | true (note no quotes, this is a Boolean not a string) | false |
An example with all options set:
$('#myelement').sbscroller({ handleImage:'/images/misc/scrollbar-handle-middle.png', handleTopImage:'/images/misc/scrollbar-handle-top.png', handleBottomImage:'/images/misc/scrollbar-handle-bottom.png', handleGripImage:'/images/misc/scrollbar-handle-grip.png', autohide:true });
Mousewheel support
The plugin automatically supports Brandon Aaron’s mousewheel plugin. If the plugin is present, the mousewheel can be used to scroll. Thanks to Dimitris for this suggestion.
Methods
The plugin supports two methods:
Method | Description | Usage |
---|---|---|
refresh | Refreshes the slider. This can be called after content has been added or removed from the scrolling element, after a hidden scrolling element is displayed, or for any other reason. | $('#myelement').sbscroller('refresh'); |
reset | Resets the slider to the initial state, with the scrollbar at the top | $('#myelement').sbscroller('reset'); |
Customisation
The background to the slider and slider handle are set as a default in the css as a light grey and dark grey respectively – you can change these using css, and also change the width of the slider if you wish.
Changelog
V1.2 – 9 January 2012 – Mousewheel code amended to allow for repeated show/hide of hidden elements, and to alter the scroll speed dependent on the height of the scrolled element (as opposed to moving a fixed percentage).
V1.3 – 9 January 2012 – Mousewheel code amended to run automatically if mousewheel plugin is present, mousewheel option removed.
V1.4 – 17 January 2012 – Amended to cope with the height of the scroll pane being changed – thanks to JustPie for pointing this omission out.
V1.5 – 12 February 2012 – Amended to cater for the ‘refresh’ being called when the scroller has not previously been set – the code now tests this and sets up the scroller if it doesn’t exist.
V1.6 – 6 March 2012 – Removed the unnecessary wrap with .scroll-container (this was a legacy of floating the scrollbar instead of using absolute position).
V1.7 – 5 September 2012 – Added a reset method.
V1.8 – 12 November 2012 – Corrected a typo in the script affecting the handleImage
option.
V1.9 – 29 January 2013 – Amended code to cope with non-html content in the scrolled element option.
Download
Zip file containing javascript and css files (4kB)
Can I use this on my site?
Probably. See my policies on using code from this site.
Don’t link directly to the files on this site – that eats up my bandwidth. Create a copy on your own server.
Using the plugin with touchscreens
As it stands, this will not work with touch screens as jQuery UI does not itself support touch events. I have done only limited testing on an iPad, but TouchPunch seems to address this nicely. Just include it on your page. Don’t currently have access to a touchscreen device, so if you do use TouchPunch, let me know how you get on.
Using the plugin with jQuery UI css
This plugin cannot be styled directly using the jQuery UI css themes – the images supplied do not work well with a vertical, as opposed to horizontal slider, and the vertical slider requires an additional enclosing element for the slider, with the result that the wrong element is styled. However, it should be pretty straightforward to adapt your css to pick up the jQuery UI css styles if required. You can find an example which replicates the ui-lightness theme here.
Linked to this, if you are using jQuery UI css on your page as well as sbscroller.css then there is some interference between the two. This can be overcome by some additions to sbscroller.css which you can download here (1kB). If you’re not using images for the handle you also need to set the background-image to none on .ui-slider-handle
.
Using the plugin with WordPress
If you want to use this in WordPress, then the recommended way of adding all the scripts is to add the following to your functions.php:
function sb_scroller_scripts() { wp_enqueue_script( 'jquery' ); wp_register_script( 'jqueryui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js'); wp_enqueue_script( 'jqueryui' ); wp_register_script( 'sbscroller', get_template_directory_uri().'/js/jquery.sbscroller.js'); wp_enqueue_script( 'sbscroller' ); wp_register_style('sbscrollercss',get_template_directory_uri().'/jquery.sbscroller.css'); wp_enqueue_style('sbscrollercss'); } add_action('wp_enqueue_scripts', 'sb_scroller_scripts');
This assumes you have jquery.sbscroller.js in your templates file and jquery.sbscroller.js in a subfolder called js. If you’ve already got jQuery loaded you don’t need the first line. This will load all the jQuery files and the css file in your header. You can also manually edit your header.php to include the files.
Then on the page you want the scroller to appear, add the following via the html tab:
<script type="text/javascript">
jQuery('#myelement').sbscroller();
</script>
Note that you have to use jQuery in full here since WordPress applies jQuery.noConflict() by default, which means the $ shortcut won’t work.
Stefan
It works fine with jQuery 1.10.2 and jQuery UI 1.11.2 – I have updated the demo. You may have been using incompatible versions of jQuery and jQuery UI.
tried it with jquery 1.10.2 and unfortunately it does not work with that version (I am aware that the spec above says jquery 1.7.1). Just to let anyone know how also tries.
You can just add the code directly into your template if you need to, or have a look at the section about WordPress at the bottom of this page.
love this! thx so much for the work!
i was wondering how this can work on a wordpress theme. I have one that I want to use but the columns on the landing page are fixed and I would rather have it scroll so folks dont have to click anything to see extra content. just want them to scroll.
thanks in advance
Hello Barna
I can’t recreate this at all, and I’ve had no other reports of this. Can you give a link to your page?
UPDATE FOR OTHERS: The problem manifested only in Chrome, and is caused because Chrome (Webkit) calculates div heights without images at $(document).ready(), giving unexpected behaviour in this case. The solution is either to delay setting up the slider until $(window).load() or to fire a refresh at this point.
Hi, I use the vertical plugin, but the scrollbar gets constantly wrong height value, when I press F5 more times. More exactly , the .slider-vertical div has changing height, and top-margin values, even the content is fixed, doesn’t change. What should I check in my code to correct this behaviour? Eg. 5 times has the correct value, but the 6th time has lower height, and higher top-margin value.
Thanks
I’m not seeing that on iPhone/Safari. To be honest the slider doesn’t work well with touch screens in any case.
Hi,
I have a problem on mobile phones. The .scroll-content div is not resizing past a certain height so the scroller only shows part of the text. Example can be seen here: http://sibincic.bobr.si/podrocje-dela.php
Any idea what could be causing it?
The latest version of the mousewheel code or the latest version of jQuery? If the latter this comment from Dirk Kirkland (actually on the non-plugin version) may help.
I really love this, but I’m having a ton of issues with the mousewheel.
Any suggestions regarding the latest version?
Yes, almost, seems OK in Chrome, Safari and Opera, but something slightly different happens in IE. Don’t have time to look in depth at the moment, but I will investigate at some point.
But Firefox and Safari don’t find objects in non-visible areas. So the problem only occurs with Chrome, Opera and IE. I search for “15” (demo example), the browser automatically scrolls down and it triggers.
If I search with Firefox and Safari nothing happens. It doesn’t find the “15”. It doesn’t scroll down automatically. No bug, so no need to trigger and fix.
The trigger works as it should. Only establishing the scroll position may be difficult.
The following code does the trick, but it’s not optimal 😉
$(‘.scrollpane’).scroll(function() {
$(‘#scrollpane1’).sbscroller(‘refresh’);
});
That doesn’t work in Firefox unfortunately, and seems hit and miss in Safari.
I’ve looked at this before where a user had a form within the scroll area and was navigating down it by tabbing. Although in this case I could reliably capture the event, there was no way of reliably establishing the resulting scroll position and reestablishing the scrollbar, and I suspect the same is true here.
You could trigger it with .scroll().
http://api.jquery.com/scroll/
$(‘.scrollpane’).scroll(function() {
alert(‘trigger’);
});
It works very good. I tested it.
Alex
Yes, good spot. I don’t think this can be fixed as you’d need to trap the browser search event to do so, and this would be very bad practice.
This discussion covers some of the reasons why.
Great plugin, but I found a little bug (testet with Chrome and Opera).
Try to search something, that isn’t in the visible area.
For example search “15” (with STRG+F) on the demo-page.
Thanks – use the ‘Buy me a drink’ button on the left hand side.
basically i am working with a development company.
and i need an alternative for default scroll bar.
how can i make donation
If it’s for a client site, for which you’re being paid, then a small donation is appreciated.
Thankypu Simon
basically its for client site, i m creating it,
Do you mean can you use it on your own site? Yes, you can.
Hello Simon
thanks. you have created a great scroll bar plug in. I wish to use it on my live site. Is there anything i can do for it.
have a nice day
Asim
Thanks for your comments. I’ve amended the plugin per your suggestion – this hasn’t come up as an issue before. Minified? Well, it’s currently 8kB, so marginal savings by minifying, and I think, outweighed by the benefit of having readable code. Cheers though!
Hello. Great job with the plugin. There is one very minor bug, on lines 24 and 36 you should use `.contents()` method, instead of `.children()`. If the contents aren’t html tags, there is some weird misbehavior. Also minified version of this excellent plugin is a must. 🙂
Thanks Jeremy
For info to others, I cannot currently replicate this behaviour using FF17.0.1.
Thx, logical, for sure.
Another thing:
When using mousewheel to browse your sbscroller, if the page itself has a (native) scrollbar, it’s scrolling also, at a lower speed than the sbscroller.
This behaviour is related to new event wheel introduced in FF 17:
https://github.com/brandonaaron/jquery-mousewheel/issues/45
You have to beautify (unminify) jquery.mousewheel.3.0.6.min.js and change line 21 from
var b = [“DOMMouseScroll”, “mousewheel”];
to
var b = [“DOMMouseScroll”, “mousewheel”, “wheel”];
Tested in Chrome and FF17, and seems to work
Jeremy
Yes, if the element is hidden it has no height and no scroller is created.
If you call the refresh method when the element is un-hidden, then the scrolbar will be created correctly.
Apparently, the css rule display: none on the target element prevents the sbscroller to exist. You have to make it visible at load and hide it by JS to make sbscroller work properly
I added ‘jquery-ui-slider’ as a dependency and it worked.
You need Slider as well as core. Personally, I find it easiest to link to the Google CDN for jQuery UI.
the “jquery.ui.core.min.js” is loaded. It’s a dependancy for the scroller script (see the line with wp_enqueue_sript, i.e. array(‘jquery’,’jquery-ui-core’)). I’ve just checked the page — yes, it is there.
If that’s not enough, perhaps you could tell me what “modules” of jQuery UI should I load?
Roman
The error message suggests you might not have jQuery UI loaded – this is needed as well as jQuery.
Hi!
I try to use this script in a WordPress project. I add it this way:
function scroller(){
wp_enqueue_script (‘vertscroller’, get_bloginfo(‘template_directory’).’/scroller/jquery.sbscroller.js’, array(‘jquery’,’jquery-ui-core’), false, false);
}
add_actions(‘wp_enqueue_scripts’,’scroller’);
and on the page I get a javascript error:
‘undefined’ is not a function evaluating ($scrollpane.find(‘slider-vertical’).slider’)
it’s on line 79 of jquery.sbscroller.js
what could it be? can I somehow fix it?
Bogdan
I don’t understand what you mean I’m afraid.
Could I replace vertical sliders of html combox with tag select? I tried it not work.
Amay
Having lists shouldn’t affect how the slider works, pretty much any content enclosed within the scrolled element will be OK.
how would i add vertical slider on my page?in my div i will have link lists..
i ve added a touhc functionality to the plugin, using the touchwipe plugin, its really simplified, for my case, but easily modify-able
heres my plugincode ->http://jsfiddle.net/DD4Ec/
ive modifierd the code at the end, it wstarts with wipeScroll if i remember correctly.
Jeroen
I’ve added this as an additional method to the plugin – see the page for details.
Is there an option to move the scrollbar back to top, this would be helpfull in a jquery tabs setup after reopening a previous tab with a changend scrollbar position.
Marc
Best to trigger this via the stop or maybe the slide event which jQuery UI slider supports – see here for details.
Hi,
how do I specify a javascript callback to be executed with the “onscroll” event?
Hi Mummi
Yes, the plugin doesn’t support touch devices currently.
nice plugin, but i have some problems with an mobile approach, nowadays those pluins should work with touch and swipe events…
i just wrote in the plugin using the touchwipe plugin.. but the target data has problems… and wont scroll…
Harry
I think in fact you’ve answered your own question – if you assign a max-height rather than a height to the div, then no scrollbar is created if it’s not needed, and if the content exceeds the max-height then a scrollbar is set up.
Hi Simon,
Really great plugin that we’re starting with! We have an element that changes height depending on the amount of text. Previously, we had no fixed height and it would add the (old) scroll only if the max height was reached. Is there a way to use your scroll without a fixed height because now we cannot dynamically change the height?
Cheers!
Julian
The plugin doesn’t support autoscroll – but if you have a look here I have a non-plugin version that might do what you want.
View the source to see how it’s done.
How do I make the content in the plugin autoscroll on page load and reset to the first element when I reach the last.
JustPie
Thanks for your interest (again). Re the mousewheel issues if the slider is refreshed, I’ve already fixed this in version 1.2 by simply removing the mousewheel and re-instantiating it. Moving the mousewheel code outside setSlider() will work, but the mousewheel scrolling will not change to reflect any change in height of the scroll pane.
I have made a few improvements / bug fixes to the plugin. I commented all changes.
http://pastebin.com/yhEYQDk8
Hi Simon,
Got the scroller to fit where I wanted it to! Thanks so much, I donated a couple of drinks for you!
Cheers,
Ann
Hi Simon,
Love your script it was so easy to plugin! One question: Is there a way to change the height of the scrollbar so that it is shorter than the element that is being scrolled?
Thanks,
Ann
I’ll have a look at this sometime in the next week or so.I’ve had a quick look at this. There are two major issues with using the jQuery UI css. First, the images that jQuery UI css uses for the slider handle background are designed for a horizontal slider, not a vertical one, so they don’t work well. Secondly, jQuery UI css applies images to the background of the
.ui-slider
element, which does not extend to the top and bottom of my scrollbar (instead you would need to style its parent element.slider-wrap
.Major changes would be required to resolve these, which frankly don’t seem worthwhile to me. It’s simple enough to amend your css to replicate the style of the jQuery UI css.
Related to this, if the jQuery UI css is used on the same page as sbscroller.css then there is some interference. The following amendments to sbscroller.css should overcome this:
Is it possible to get your plugin to use the jQuery UI theme? It would be nice if your scrollbar looked like the ui-slider.
I don’t see a problem with the mousewheel myself.
If you have a trouble with mousewheel event (jQuery 1.7.+), you can fix it. Just replace:
if ( event.detail ) { delta = -event.detail/3; }
to
if ( event.originalEvent.detail ) { delta = -event.originalEvent.detail/3; }
@John:
Jquery-ui doesn’t support touch devices as of the latest version, but there are libraries out there such as jquery.ui.touch-punch.js which add the compatibility into jquery-ui. However, I think it’d be better to use Jquery Mobile since that seems to be what is better supported on touch-capable devices.
Marc
I tested on FF, Chrome, Opera, Safari and IE6+, as it says on the plugin page. I don’t see the behaviour you describe on FF10 on W7, so it may be restricted to Mac.
hey there!
I bet you use Chrome to test because it works well on Chrome.
But on Firefox 10.0 (and previous versions), when you do a fast scroll-up on the touchpad (Macbook) when the scrollbar is at the top-most position then you should see some very crazy jittering… Normally. jQuery slider doesn’t work with mousewheel events so I assume you added that and so the bug is either in the mousewheel plugin or your code, but I’d think in the former.
Try it out yourself and see..
Marc
I haven’t tested it myself on a mobile device. The issue is really whether jQuery UI works consistently on mobile devices – I suspect the answer is no at present.
I am wondering if this plugin has support for touch devices ?
Thanks for pointing this out. I have amended the plugin to cope with this – version 1.4.
I noticed that the scrollbar doesn’t resize correctly if you resize the parent element. This can be fixed by removing moving line 67: ” $scrollpane.find(‘.slider-wrap’).height(Math.round($scrollpane.height())); ” outside of the scope of the if statment that its currently in.
Hope this helps someone out.
You could do this by using
.find('.slider-vertical').slider("value", 0)
;
on the scrolled element.How can I position the scrollbar at the bottom after a ‘refresh’?
This amendment is included in V1.2.
The mouse scrolling speed is dependant on the content. So if there is a lot of content the scrolling is incredibly fast, and if the content is just a little bigger than the container than the scrolling is very slow.
Can you help me find a way to make the mouse scrolling speed constant (independent of the content length)?
i was seriously going nuts trying to make this work (ui slider as vertical scrollbar), nice work, thanks…
it even fits my need to scroll a previously hidden element:)
one suggestion… you could tweak so you don’t need a mousewheel option very easily, just replace
if(settings.mousewheel){
with
if($.fn.mousewheel){
and when mousewheel is available it is “auto-detected”
Your html can be pretty much anything you want – your container element (normally a div) needs to have a fixed height, and the content that you want to scroll obviously needs to be within that html element. It doesn’t matter what id or class you apply to your chosen element – you can use that to identify the element and apply the
. sbscroller
method in the same way as any other jQuery method.What should I write in my HTML, and what kind of ID should I use to the HTML element in order to use this plugin?
Jeroen
Not sure if that is a real email address otherwise I would have sent you a mail. You shouldn’t need to add any css other than the file that comes with the plugin.
If it’s still not working can you send me a link, because otherwise I’m only guessing….
hello,
I want to use your jquery plugin to customize the scroll-bars of a div. but I can’t get it to work. What do I surely have to put in the css code of my div ‘updates’ where I want scroll bars??
Thanks