Tabs

by andfinally

HTML

<div id="tabcontainer">
    <div id="tab1" class="tab">Tab 1</div>
    <div id="tab2" class="tab">Tab 2</div>
    <div id="tab3" class="tab">Tab 3</div>
    <div id="tab4" class="tab">Tab 4</div>
    <div style="clear:both;"></div>
    <div id="tabarea1" class="tabarea">This is all the stuff in Area 1. <div style="width:200px;height:200px;background:blue;"></div></div>
    <div id="tabarea2" class="tabarea">Followed very quickly by all the stuff in Area 2, which is quite a lot of stuff I believe. <p style="width:200px;height:300px;background:green;"></p>Yes, a great deal of stuff. And so on and so on, I could go on a very long time if I chose: and I do.</div>
    <div id="tabarea3" class="tabarea">Matter of Area 3.</div>
    <div id="tabarea4" class="tabarea"><div style="width:100px;height:100px;background:indigo;"></div>Here is the detail of the fourth area, which, though fairly long, is not as long as the stuff in the second area.</div>
</div>

<div id="output"></div>

CSS

#tabcontainer { width: 500px; margin: 50px auto; border: 1px dotted violet; }
.tab { float: left; width: 100px; height: 25px; border: 1px solid #999; padding: 10px; }
.tabarea { border: 1px solid #999; padding: 10px; }

#output { margin: 50px auto; }

JavaScript

MetroMootools = {};

MetroMootools.log = function(msg) {
    console.log(msg);
};

MetroMootools.Tabs = new Class({

    Implements: [Options, Events],

    options: {
        buttonArrayStr: '',
        areaArrayStr: '',
        startingPosition: 0,
        buttonSelectedCSSClass: 'selected'
    },

    initialize: function(wrapperElm, options) {
        MetroMootools.log(document.getElementById(wrapperElm));
        this.wrapperElm = $(wrapperElm);
        this.setOptions(options);
        this.setProperties();
        this.setEvents();
        this.animating = false;
        this.setUpOrigStyles();
    },

    setUpOrigStyles: function() {
        this.areaArray.each(function(item, index) {
            if (this.areaArray[this.count] != item) {
                item.setStyles({
                    'opacity': '0',
                    'display': 'none',
                    'visibility': 'hidden',
                    'zoom': '1'
                });
            }
        }.bind(this));
    },

    setProperties: function() {
        this.count = this.options.startingPosition;
        this.prevElm = null;
        this.buttonArray = this.wrapperElm.getElements(this.options.buttonArrayStr);
        this.areaArray = this.wrapperElm.getElements(this.options.areaArrayStr);
        this.createOpacityObjects();

        this.effects = new Fx.Elements(this.areaArray, {
            link: 'ignore',
            duration: 250,
            transition: Fx.Transitions.Sine.easeIn,
            onStart: function() {
                MetroMootools.log('animation started');
                this.animating = !this.animating;
            }.bind(this),
            onComplete: function() {
                MetroMootools.log('animation ended');
                if (this.animating) {
                    this.areaArray[this.count].setStyle('display', 'block');
                    var newHeight = this.areaArray[this.count].getSize().y;
                    this.startHeightTransition(newHeight);
   ...