Over a million developers have joined DZone.

ZebraStripes

·

/*
 * 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)
Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}