Before moving into the construction of object literals, which is my preferred method of organizing my scripts, I want to take a post to discuss the get() method in the X library. The functionality the get() method provides is as follows:

  • return an element by its id
  • return an element or elements by class name
  • return an element or elements by tag name
  • given a context, return only elements within it via the above methods

Pretty straightforward yes? To save on the typing, let’s construct the method so that a search for an element use the css selectors ‘#’ for id, and ‘.’(a period) for class like so:

    X.get('#spam');

will return an element with id=”spam”, and to fetch all elements with class=”eggs” you would use:

    X.get('.eggs');

Finally a tag name search would just require the name of the tag:

    X.get('div');

This would return a node list of all div tags on the page. The use of a context argument:

    var divs = X.get('div'),
    //get only a tags in the 3rd div
    var anchors = X.get('a', divs[2]);

You could just pass the function as well:

    //get only a li elements in a certain ul
    var lis = X.get('li', X.get('#certain_ul'));

You get the idea…

Here’s the code for the method:

X.get = function(what, where) {
 
    //context is document by default or self if included
    where = where || document;

    //remove where from an array-like structure if needed
    //this is necessary with recursive use of get()
    if (where.length) {
        where = where[0];
    }

    var selector = what.substr(0, 1),
    name = what.slice(1),i,
    getArray = [], gotArray = [],
    pattern = new RegExp("(^| )" + name + "( |$)");
    //have queryselector or queryselectorall?
    switch (selector) {

        case '#': //is a get by id
            return where.querySelctor ? where.querySelctor(what) :
                where.getElementById(name);
            break;

        case '.': //is a get by class name
            //ie browsers...
            if (typeof document.all != "undefined") {
                //is there queryselectorall?
                if (where.querySelectorAll) {
                    return where.querySelectorAll(what);
                }
                else {
                    getArray = where.all;
                } //no ternary here because of unrelated results  
            }
            else {
                //Is there querySelectorAll()?
                if (where.querySelectorAll) {
                    return where.querySelectorAll(what);
                }
                else { //if not queryselectorall support
                    getArray = where.getElementsByTagName("*");
                } //same as above as far as ternary goes...
            }

            for (i = 0; i < getArray.length; i++) {
                if (pattern.test(getArray[i].className)) {
                    gotArray[gotArray.length] = getArray[i];
                }
            }
            return gotArray;
            break;

        default: //is a get by tag name
            return where.querySelectorAll ? where.querySelectorAll(what) :
                where.getElementsByTagName(what);
    }
};

A selector is gotten by slicing off the first ‘letter’ of the passed in identifier. The switch statement looks at that selector to decide what query to pursue. The root of the query is assigned as document by default (resulting in document.getElement….) or reassigned as the passed in context if one was passed. The getElementById query (‘#…) checks first for the newer w3 querySelector() support which is present in the newest versions of most browsers (including IE8 to some degree), then falls back to the old standard if false. The search by class name is slightly more complex only because there was no standard DOM method to query by class until querySelectorAll() (which, again, is only in the newest of browser versions). When this segment of the case is entered a quick IE vs standards check is conducted (IE will use document.all) and if no querySelectorAll() support is present the 2 arrays created and the RegExp are used to:

  • getArray – Holds all page elements
  • pattern – Test each element for the passed class name
  • gotArray – Hold all elements which pattern.test() returns true

gotArray is then returned. The last piece of the switch, fetch by tag name, is as simple as ID querying because of the presence of the native DOM method getElementsByTagName(). Again used as a fall back here in the case of no querySelectorAll().

I think thats a good enough explanation of this method moving into the next post…