Mootools Sidebar Tutorial

I’ve decided to dedicate some space on my blog to Mootools tutorials. The next in this series, following the sample nav bar, is a sidebar that slides in and out! I’ve embedded the script along with this post, so if everything is working right and you’ve got CSS and JavaScript enabled, you should be able to move your mouse to the right edge of the screen to see the sidebar in action.

Once again, we’ll start off with the HTML:

<div id="side_bar">
  <img src="logo.png" />
  <ul>
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 2</a></li>
    <li><a href="#">Link 3</a></li>
    <li><a href="#">Link 4</a></li>
  </ul>
</div>

This will be the structure of our sidebar. The only reason I used side_bar as an id instead sidebar is because I’ve already used sidebar in my blog layout. Otherwise there’s nothing special going on here, just a div that wraps the content, an image to jazz it up, and an unordered list.

And here is the CSS:

#side_bar {
  height:100%;
  font-family:Arial, sans-serif;
}
#side_bar, #side_bar a {
  color:#fff;
}
#side_bar a {
  display:block;
  padding:12px 10px 10px;
  text-decoration:none;
  width:129px;
  height:19px;
  font-size:14px;
  margin-bottom:1px;
}
#side_bar a:hover {
  background:url(link_bg.png) no-repeat;
}
#side_bar ul {
  list-style:none;
  margin-left:20px;
}
#sidebar_wrapper {
  position:fixed;
  right:0;
  top:0;
  overflow:hidden;
  height:100%;
  background:url(sidebar_bg.png) repeat-y left;
}

You’ll notice that there’s an id that we’re not using in the html #sidebar_wrapper. We’ll be creating this with javascript. The only relevant CSS is applied to this class. I’ve decided to set position: fixed to make things easier. Remember IE6 doesn’t support this value so we’ll have to account for that with JavaScript. I’ve also hidden any overflow and attached it to the right of the screen. This is what allows the effect to slide out from the right instead of the left.

Now we’ll take the JavaScript in steps:

window.addEvent('load', function () {
...
});

As always, when manipulating DOM elements, we have to wait for them to load, which is why we wrap all functionality in this event.

var sidebar = new Element('div', {
  'id':'sidebar_wrapper'
}).adopt($('side_bar')).injectInside(document.body);
var sidebarWidth = sidebar.scrollWidth;
var effect = sidebar.effect('width', {
  'duration':400,
  'transition':Fx.Transitions.Quint.easeOut,
  'wait':false
});
var hide = 20;

Here we grab our sidebar, stick it in a new element (with an id of sidebar_wrapper), and inject that element into the body. This way, we don’t have to mess with z-index values. We need to use a wrapper otherwise the content will start wrapping as the width gets smaller. We also want to save the original width so we can restore it later.

Next, we create the heart of this tutorial, the effect. It will adjust the width of our sidebar, using the options we’ve supplied: 400 millisecond transition and quintic ease out animation. I’ve explained what wait: false does before, but here’s a good tip. If an element has two effect states based on user interaction, it’s probably necessary to set wait to false. Finally, we set hide to 20. This is the size the sidebar will collapse to.

Here’s the next chunk:

sidebar.addEvents({
  'mouseenter': function () {
    effect.start(sidebarWidth);
  },
  'mouseleave': function () {
    effect.start(hide);
  }
});

To toggle the sidebar display, I’ve decided to add mouseover and mouseout events, except I used a couple custom events that Mootools supplies. These events correctly calculate when the mouse enters and leaves the sidebar.
In each event, we start the effect to adjust the sidebar accordingly.

This last part is where we accommodate IE6’s ineptitude:

if (window.ie6) {
  sidebarWidth = 180;
  sidebar.setStyles({
    "position": "absolute",
    "height": window.getHeight(),
    "right": -1,
    "top": window.getScrollTop()
  });
  window.addEvent("scroll", function(){
    sidebar.setStyle("top", window.getScrollTop());
  });
}
effect.set(hide);

Mootools automatically sets window.ie6 if the browser is IE6 so first we test for that. I’ve found that besides creating a scroll event for the window that emulates position:fixed, the sidebar width or height in IE6 isn’t calculated correctly, forcing us to set it ourselves. Also, the sidebar appears to be one pixel too far left. Setting right: -1 fixes that. Finally, and this isn’t an IE6 fix, we hide the sidebar without a transition using the set() method.

That should be it! It’s also important to note that all the graphics I used are PNGs, so IE6 won’t display those correctly either. You can download fixpng.js from the cnet mootools svn if you really need it to work in IE6.


4 Responses to “Mootools Sidebar Tutorial”

  1. Jonah Dempcy

    Nice Mootorial!

    I see you do window.addEvent('load') instead of window.addEvent('domready') … Is there a reason for this?

    The ‘load’ event only triggers once every image on the entire page is finished downloading. On the other hand, ‘domready’ triggers as soon as the DOM is ready for manipulation.

    -Jonah
    http://www.thetruetribe.com

  2. Jonah Dempcy

    One other thing I noticed: This is going to be a performance kiler:

      window.addEvent("scroll", function(){
        sidebar.setStyle("top", window.getScrollTop());
      });

    Instead, you should set a timer so it auto corrects after 250 milliseconds or so. That way, it will be throttled and not constantly spamming the getScrollTop() method, thus bringing most browsers to a screeching halt when rapidly scrolling up and down.

    For instance, try this instead:

      var timer; // make sure this is global
      window.addEvent("scroll", function(){
        if (timer) clearTimeout(timer);
        timer = setTimeout(function() {
            sidebar.setStyle("top", window.getScrollTop());
        }, 250);
      });
  3. Chris

    Jonah,

    I’ve seen occasional bugs about domready not working in IE6, so I stick with load most of the time.

    Note that I only attach the scroll event if the browser is IE6, but that is a good suggestion about the timer. Thanks.

  1. chromaSYNTHETIC Journal » Blog Archive » Mootools Demo Redux
    Pingback on August 5th, 2007 at 8:41 pm

Leave a Reply