O'Reilly

Introducing MooTools ScrollSidebar

By on  
Side ScrollBar

How many times are you putting together a HTML navigation block or utility block of elements that you wish could be seen everywhere on a page? I've created a solution that will seamlessly allow you to do so: ScrollSidebar. ScrollSidebar allows you to attach an element to a place on the screen and animate the menu to the current scroll position.

The HTML

<div id="sidebar-menu">
	<ul>
		<li><a href="#pagetop" id="sidebar-menu-top" title="Top of Page" style="background:url(menu-up-arrow.png) center center no-repeat;">Top of Page</a></li>
		<li><a href="/" style="background:url(menu-home.png) center center no-repeat;" title="Go to the Homepage">Homepage</a></li>
		<li><a href="http://twitter.com/home?status=I love David Walsh's blog!  MooTools, CSS, jQuery, PHP...it has everything!" id="sidebar-menu-twitter" style="background:url(menu-twitter.png) center center no-repeat;" title="Share on Twitter">Post on Twitter</a></li>
		<li><a href="#pagebottom" id="sidebar-menu-bottom" style="background:url(menu-down-arrow.png) center center no-repeat;" title="Bottom of Page">Bottom of Page</a></li>
	</ul>
</div>

You may code the menu's HTML any way you'd like. For the sake of accessibility and semantics (I literally just shivered at the thought of following semantics) I've used an HTML list.

The CSS

#sidebar-menu	{ display:none; width:48px; background:#333; border:1px solid #000; padding:10px; -webkit-border-radius:10px; -moz-border-radius:10px; }
#sidebar-menu ul{ padding:0; list-style-type:none; }
#sidebar-menu a	{ color:#fff; display:block; height:48px; width:48px; text-indent:-3000px; overflow:hidden; }

You may code the sidebar menu any way you'd like too. No need to worry about positioning the menu though -- the plugin will override that anyway. I highly recommend addressing the menu's width. I'm also defaulting the menu to display:none until the menu can be positioned.

The MooTools JavaScript

var ScrollSidebar = new Class({
	
	Implements: [Options],
	
	options: {
		offsets: { x:0, y:0 },
		mode: 'vertical',
		positionVertical: 'top',
		positionHorizontal: 'right',
		speed: 400
	},
	
	initialize: function(menu,options) {
		/* initial options */
		this.setOptions(options);
		this.menu = $(menu);
		this.move = this.options.mode == 'vertical' ? 'y' : 'x';
		this.property = this.move == 'y' ? 'positionVertical' : 'positionHorizontal';
		/* ensure a few things */
		var css = { position: 'absolute', display:'block' };
		css[this.options.positionVertical] = this.options.offsets.y;
		css[this.options.positionHorizontal] = this.options.offsets.x;
		this.menu.setStyles(css).set('tween',{ duration: this.options.speed });
		/* start listening */
		this.startListeners();
	},
	
	startListeners: function() {
		var action = function() {
			this.setPosition($(document.body).getScroll()[this.move] + this.options.offsets[this.move]);
		}.bind(this);
		window.addEvent('scroll',action);
		window.addEvent('load',action);
	},
	
	setPosition: function(move) {
		this.menu.tween(this.options[this.property],move);
		return this;
	}
});

/* usage */
window.addEvent('domready',function() {
	$('sidebar-menu').set('opacity',0.8); //opacity effect for fun
	var sidebar = new ScrollSidebar('sidebar-menu',{
		offsets: {
			x: 20,
			y: 20
		}
	});
});

I wont bore you with the parameter/option descriptions as they're self-explanatory. I've kept the class very simple. For those who care to see what the functionality looked like pre-Class, here you go:

//paired with smooooothscroll
new SmoothScroll({ duration:300 });
//vars
var menu = $('sidebar-menu'), offsetY = 20, offsetX = 20, speed = 450;
var setPosition = function(top) {
	var scroll = $(document.body).getScroll();
	menu.tween('top',scroll.y + offsetY);
};
//settings
menu.set('tween',{ duration: speed }).setStyles({
	position: 'absolute',
	right: offsetX,
	top: offsetY,
	opacity: 0.8
});
//events
window.addEvents({
	scroll: setPosition,
	load: setPosition
});

As you can probably tell, the functionality was begging to be placed into plugin format.

Have any feature suggestions? Share them. If you're looking for a sweet jQuery version, please head over to CSS-Tricks to see Chris Coyier's take!

Track.js Error Reporting

Recent Features

  • 6 Things You Didn&#8217;t Know About Firefox OS

    Firefox OS is all over the tech news and for good reason:  Mozilla's finally given web developers the platform that they need to create apps the way they've been creating them for years -- with CSS, HTML, and JavaScript.  Firefox OS has been rapidly improving,...

  • fetch API

    One of the worst kept secrets about AJAX on the web is that the underlying API for it, XMLHttpRequest, wasn't really made for what we've been using it for.  We've done well to create elegant APIs around XHR but we know we can do better.  Our effort to...

Incredible Demos

  • Editable Content Using MooTools 1.2, PHP, and MySQL

    Everybody and their aerobics instructor wants to be able to edit their own website these days. And why wouldn't they? I mean, they have a $500 budget, no HTML/CSS experience, and extraordinary expectations. Enough ranting though. Having a website that allows for...

  • jQuery Link Nudging

    A few weeks back I wrote an article about MooTools Link Nudging, which is essentially a classy, subtle link animation achieved by adding left padding on mouseover and removing it on mouseout. Here's how to do it using jQuery: The jQuery JavaScript It's important to keep...

Discussion

  1. Nicely done! I might find a use for that someday.

    That kinda reminds me of the “top of page” link that appears only when detecting that the user had scrolled farther then X pixel down… what was the name… ah! ScrollSpy (http://davidwalsh.name/js/scrollspy)!

  2. kolin

    nah, not a fan of these kind of things, i find them slightly annoying, in that ‘go away’ fashion reminicent of late 90’s “congratulations, you’re our millionth visitor, you’ve won an ipod FLASH FLASH FLASH” popups that follow you everywhere.

  3. Not a fan of these “replacements”. Especially not this one since each click works like a new page in firefox and makes you click the back button the same amount of times you’ve used the scroll-sidebar.

  4. Great stuff.

    Is there a reason you don’t cache $(document.body) instead of “grapping” it ever time there’s a scroll event?

    @kolin – Like all design, implementation is key. I agree that tweening does have that “FLASH FLASH FLASH!!” feeling, I prefer to just set the position as though it’s CSS is fixed. And so I’ll take this class, and implement my own setPosition method.

  5. @kolin: Hahah, true. That’s why I may not use it in public website, where the uses are limited (#top, #bottom, twitter, contact… but that’s pretty much all) but more into an admin panel or specific site where tools could be needed (Deleting stuff such as pictures, posts, comments; switching style; dragging tools; purchase carts…).

  6. not a fan at all of the scrolling effect. Why are you using javascript at all to keep it positioned? It makes it choopy, and in my mind, very unprofessional looking
    What’s wrong plain old CSS? In fact, the whole thing could be done completely in CSS and be just as nice. The only thing you need Javascript for would be to make it scroll up/down, instead of jump up/down to the links

  7. @kolin: No way! The first thing i thought of was of the 90’s mouse chasers. I have seen this effect used well for login boxes before though. on page resize it was used to keep the box in the center at all times.

  8. Louis W

    Why would I want to instantly scroll to the bottom of the page? It would make much more sense to just scroll down the distance of the viewport (page down).

    Also, I find the fact that the navigation element animates down after it scrolls a bit strange. Personally I would prefer if it were always fixed in the same position and never scrolled.

  9. Whoa — I didn’t expect so many people to be drinking the haterade on this one. I think it’s very tasteful. My example would be too big for a production site but I needed it to be noticeable for the sake of the example.

    And saying it’s the same as a mouse-chaser is nuts!

  10. I fail to see the need for a ‘scroll to bottom’ button, but I think the concept is a useful one. Maybe I would remove the animation. Maybe I would scale it down. Maybe I would stick a login box in there, or a shopping cart (as has been suggested), but I certainly won’t be having kittens over this lovely piece of code David has written for mass general consumption.

    Good job Mr Walsh!

  11. Yeah, I guess im not really a fan of these either.

    But… David, if you could figure out a way to make a the browser back buttons scroll back the position it was at, you would have a winner.

    @Marcus If you want to not store all the anchors in the history (but still want them for bookmark purposes) you can use document.location.replace, but it wont work in webkit browsers(still adds a history item).

  12. Q_the_Novice

    I agree with the consensus, this is the type of scroll that gives you the same feeling as your psycho ex – it just wont leave u alone!!!

  13. The-F

    Nice!
    Is there anyway to make the scroller start after some defined height or stop after some defined position?
    Sample (Mootools v1.1): http://demo.gavick.com/joomla15/nov2009/

  14. excellent work dude!!!!

    Thanks

  15. Hi David,
    Thanks alot for this cute scroller class.
    I used it.
    I had a main question about Mootools (or Javascript) which I found it again in your code:

    initialize: function(menu, options) {
    	/* initial options */
    	this.setOptions(options);
    	this.menu = $(menu);	
    }

    In initialize function you set this.menu with a reference to menu element. I want to know if this is a performance issue or not?
    I usually use element id instead of element reference, and when I need it use $ function to get element.
    Which is better? use $ function one time and store a reference to element in class or store a string (id) and then use $ function whenever you need it?

    BTW: I read an article about javascript garbage collection a few month ago, and there, he said about DOM element references and events and confusing browsers garbage collection method.

    This is a question which conflicts me! Help me please.

    Thank you.

  16. Valentina

    Hello,
    i have a question, could you help me, please?
    I’d need to stop this menu at bottom of the page, before of footer.
    Could you tell me the java code to do it?
    Thank you so much

  17. Dave

    Any suggestions how I can use this to have it float over a table?

    Thanks

  18. Yah I’ve been looking for a script like this that can be told to stop at a certain point – most likely at some distance from the top or from the bottom. How easy would it be to add that to the script?

  19. bill

    can i install joomla website if yes how
    thanks

  20. Basta

    Can i change the position of the bar to positionate it horizentaly?? Could anyone help me to do it?
    Thanks

  21. This is really cool. I want to use it to place a mini-chatroom that is constantly floating. However, I need to let users have the option to close/open the floating bar at will. So for example when a user clicks “close” the entire bar will be reduced or collapsed into a bar that says “open” or something like that. PLEASE PLEASE can you tell me how to or please add that to the script? Thanks

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Loading Static Templates for Intern Testing

    I use Intern by SitePen for all of my JavaScript functional testing.  Intern has loads of features other functional test frameworks don't and it's completely Promise-based -- something I got very used to when I used the Dojo Toolkit every day. Async test creation can...

  • Convert Video to mp3

    Let's all be honest for a moment:  we've all ... not paid for ... music.  Whether it was via a file sharing app like Kazaa or Napster, or it was downloading and seeding on bittorrent, or maybe even downloading a music video and ripping its audio,...

  • Sort git Branches by Date

    I'll be first person to admit I don't do as much git repository maintenance as I should.  I rarely delete branches which have been merged, so a git branch execution shows me a mile-long list of branches that likely aren't relevant.  The best way to find branches I've recently...

  • Best Tools and Resources for Web Professionals in 2015

    Looking for the right resources to help you satisfy the needs of your clients? On the lookout for the best tools to help you increase your revenue? Searching for the right software to help you improve your business? Well, then you’ve come to the right place....

  • JavaScript Polling

    Polling with JavaScript is one of those ugly but important functions within advanced front-end user experience and testing practices.  Sometimes there isn't the event you can hook into to signify that a given task is complete, so you need to get your hands dirty and simply poll for...