DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

ZebraStripes

08.08.2006
| 3929 views |
  • submit to reddit
        
/*
 * This script requires:
 *   1. Prototype version 1.5 or greater
 *     - Homepage: http://prototype.conio.net/
 *     - Download: http://script.aculo.us/downloads
 *   2. DomReady addon for Prototype
 *     - Homepage: http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
 *     - Download: http://www.vivabit.com/code/domready/domready.js
 */

/*
 * I needed something capable of not just unobtrusively running when a page
 * was loaded but also easily being called at my whim as a part of an Ajax
 * transaction.
 */
var ZebraStripes = {
    /*
     * Call this function when you want something striped.  It will figure out
     * how to stripe the element.
     */
    stripe: function(el) {
        el = $(el);
        switch (el.tagName) {
            case "TABLE":
                this._stripeTable(el);
                break;
            case "OL":
            case "UL":
                this._stripeNormalList(el);
                break;
            case "DL":
                this._stripeDefinitionList(el);
                break;
        }
    },
    /***************************************************************************
     * Everything below here is psuedo-private
     **************************************************************************/
    /*
     * This class name will be applied to the odd numbered elements
     */
    _altClassName: "alt",
    /*
     * This property persists the data that tells the object whether
     * to stripe (_isEven == false) or unstripe (_isEven == true) an element
     */
    _isEven: true,
    /*
     * Cycles the _isEven property of this object between true and false
     */
    _cycle: function() {
        this._isEven = ! this._isEven;
    },
    /*
     * As a part of the Ajax-friendliness, it is important that we remove the
     * alt class from elements as well as add it.
     */
    _stripeElement: function(el) {
        el = $(el);
        if (this._isEven) {
            el.removeClassName(this._altClassName);
        } else {
            el.addClassName(this._altClassName);
        }
    },
    /*
     * This works to stripe the child nodes of TABLE, TBODY, OL and UL elements.
     */
    _stripeElements: function(els) {
        els = $(els);
        if (els.length == 0) {
            return
        }
        var parent = els[0].parentNode;
        this._isEven = true;
        for (var i = 0; i < els.length; i++ ) {
            if ((parent == els[i].parentNode) && (els[i].visible)) {
                this._stripeElement(els[i]);
                this._cycle();
            }
        }
    },
    /*
     * TBODY is not necessary, but I recommend it.  I debated about striping
     * THEAD and TFOOT, but chose not to.  Might be added later.
     */
    _stripeTable: function(table) {
        table = $(table);
        if (table.getElementsByTagName("tbody")) {
            var tableBodies = table.getElementsByTagName("tbody");
            for (var i = 0; i < tableBodies.length; i++) {
                this._stripeElements(tableBodies[i].getElementsByTagName("tr"));
            }
        } else {
            this._stripeElements(table.getElementsByTagName("tr"));
        }
    },
    /*
     * This stripes OL and UL since they both have LI and only LI child nodes.
     */
    _stripeNormalList: function(list) {
        list = $(list);
        this._stripeElements(list.getElementsByTagName("li"));
    },
    /*
     * I have seen other function out there that can stripe DL, but they all
     * assumed that each DT would have only one DD following it.  That is not
     * always the case, and not the case in the project that spawned this
     * javascript.
     */
    _stripeDefinitionList: function(list) {
        list = $(list);
        Element.cleanWhitespace(list);
        var children = list.childNodes;
        var previousDt;
        for (var i = 0; i < children.length; i++) {
            switch (children[i].tagName) {
                case "DT":
                    if (children[i].visible) {
                        this._stripeElement(children[i]);
                        this._cycle();
                    }
                    previousDt = children[i];
                    break;
                case "DD":
                    if (previousDt.visible) {
                        this._stripeElement(children[i]);
                    }
                    break;
            }
        }
    }
};

/*
 * This function will go ahead and stripe all the elligible elements on the
 * page when the page first loads.
 */
function initZebraStripes() {
    var toStripe = $$("dl.striped")
        .concat($$("ol.striped"))
        .concat($$("table.striped"))
        .concat($$("ul.striped"));

    toStripe.each(
        function(el) {
            ZebraStripes.stripe(el);
        }
    );
}

Event.onDOMReady(initZebraStripes);
// Or you could substitute a different loader:
//Event.observe(window, 'load', initZebraStripes)
    

Comments

Snippets Manager replied on Mon, 2012/05/07 - 1:26pm

Yeah, I had a sarcastic comment saying "Like we need another one of these..." at the top. The main impetus for this was getting something that striped DLs with multiple DDs following a DT correctly. I've never seen that one before. ALA gave me a way to do this for tables. I liked the implementation that included tables and lists from Cody Lindley. But I didn't like the random assemblage of functions. I liked the cohesiveness of the table striping from Matthew Pennell, but it only did tables. The unobtrusiveness I learned from LightBox. I've also come to learn to love Prototype and the many ways it makes my life easier. I'm sure somebody could do the same with YUI or jQquery, though.

Snippets Manager replied on Mon, 2012/05/07 - 1:26pm

Fancy! See also http://www.bigbold.com/snippets/posts/show/351