Optimize this jQuery tab controller further How do I optimize this code further?  Goal is to edit "js-tab" in one place.  This is what I tried to follow.

Full code here.

var ToggleTab = {

init: function() {
    this.tab = $(".js-tab");
    this.bindEvents();
},

bindEvents: function() {
    this.tab.on("click", this.toggleTab);
    //this.tab.on("click", $.proxy(this.toggleTab, this));
},

toggleTab: function(e) { 
    var showTab = $(this).data("tab-content");
    e.preventDefault();

    $(".js-tab").each(function() {
        if ($(this).data("tab-content") === showTab) {
           $(".js-tab-" + showTab).removeClass("hide");                
        } else {
            $(".js-tab-" + $(this).data("tab-content")).addClass("hide");
        }
    });
}

};

$(function() {

    ToggleTab.init();

});
I've always been partial to writing JavaScript classes that take a root element:

function TabController() {
    // Maintain reference to "this" in event handlers
    this.toggleTab = this.toggleTab.bind(this);
}

TabController.prototype = {

    $element: null,

    constructor: TabController,

    init: function(element) {
        this.$element = $(element).on("click", ".js-tab", this.toggleTab);

        return this;
    },

    toggleTab: function(event) {
        var that = this,
            showTab = event.target.getAttribute("data-tab-content");
        event.preventDefault();

        this.$element.find(".js-tab").each(function() {
            var tabContent = this.getAttribute("data-tab-content");

            if (tabContent === showTab) {
                that.$element.find(".js-tab-" + showTab).removeClass("hide");                
            } else {
                that.$element.find(".js-tab-" + tabContent).addClass("hide");
            }
        });
    }
};


Plus, I like to replace jQuery API calls that wrap cross browser native DOM methods  -- e.g. $(foo).data("bar") most times can be replaced with element.getAttribute("data-bar").

And to use:

// using document.documentElement means you don't need a jQuery dom-ready event handler
var tabs = new TabController().init(document.documentElement);


While you technically only need one tabber per page, making this an instantiable class allows you to unit test your JavaScript.

describe("TabController", function() {

    var element, tabs, event;

    function FauxEvent(type, target) {
        this.type = type;
        this.target = target;
    }

    FauxEvent.prototype.preventDefault = function() {};

    describe("toggleTab", function() {

        beforeEach(function() {
            element = document.createElement("div");
            tabs = new TabController().init(element);
        });

        it("shows a tab", function() {
            element.innerHTML = [
                '&lt;a class="js-tab" data-tab-content="panel-1"&gt;Tab 1&lt;/a&gt;',
                '&lt;div class="js-tab-panel-1 hide"&gt;&lt;/div&gt;'
            ].join("");

            event = new FauxEvent("click", element.firstChild);

            tabs.toggleTab(event);

            expect($(element.lastChild).hasClass("hide")).toBe(false);
        });

    });

});


This makes your code truly modular. You could go a step further and make the CSS class names and data attributes customizable:

function TabController() {
    // Maintain reference to "this" in event handlers
    this.toggleTab = this.toggleTab.bind(this);

    this.options = {
        classPrefix: "js-tab",
        hiddenClass: "hide",
        dataAttribute: "data-tab-content"
    };
}

TabController.prototype = {

    $element: null,

    options: null,

    constructor: TabController,

    init: function(element, options) {
        this.$element = $(element).on("click", "." + this.options.classPrefix, this.toggleTab);
        jQuery.extend(this.options, options || {});

        return this;
    },

    toggleTab: function(event) {
        var that = this,
            showTab = event.currentTarget.getAttribute(this.options.dataAttribute);
        event.preventDefault();

        this.$element.find("." + this.options.classPrefix).each(function() {
            var tabContent = this.getAttribute(that.options.dataAttribute);

            if (tabContent === showTab) {
                that.$element.find("." + that.options.classPrefix + "-"
                    + showTab).removeClass(that.options.hiddenClass);
            } else {
                that.$element.find("." + that.options.classPrefix + "-"
                    + tabContent).addClass(that.options.hiddenClass);
            }
        });
    }
};


Some sample HTML

&lt;ul&gt;
    &lt;li class="js-tab" data-tab-content="content-a"&gt;&lt;a href="#"&gt;Tab 1&lt;/a&gt;&lt;/li&gt;
    &lt;li class="js-tab" data-tab-content="content-b"&gt;&lt;a href="#"&gt;Tab 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="js-tab-content-a"&gt;
    Content A
&lt;/div&gt;
&lt;div class="js-tab-content-b"&gt;
    Content B
&lt;/div&gt;

&lt;script type="text/javascript"&gt;
    var tabs = new TabController().init(document.documentElement);
&lt;/script&gt;


JSFiddle: http://jsfiddle.net/CL8Ns/