Simple CSS selector - support #id,.ClassName, @name, tagName.className, node nod

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

The realization of a simple CSS selector

Some time ago read a part of the jQuery source code, the selector (selector) realization part, feel down more difficult, so on the basis of some API usually packaging and collection, especially the DOM part of the operation, he realized a simple CSS selector, support #id,.ClassName, @name, tagName.className, node node five formats for the page element or set of elements.

Nonsense not say, with JS code:

// The DOM object
var dom = {
    // Detection of window 
    isWindow: function(obj) {
        return obj && typeof obj === 'object' && 'setInterval' in obj;
    },
    // Whether the node
    isNode: function(obj) {
        return !!(obj && obj.nodeType);
    },
    // Whether the node list
    isNodeList: function(obj) {
        // XXX call toString () method returns[object xxx]
        return !!(obj && (obj.toString() === '[object NodeList]' || 
            obj.toString() === '[object HTMLCollection]'));
    },
    // According to the ID element
    getElemByID: function(id) {
        return typeof id === 'string' ? document.getElementById(id) : id;
    },
    // According to tagName to obtain a set of elements
    getElemsByTagName: function(tagName, root) {
        var elems = (root || document).getElementsByTagName(tagName);
        return elems !== null && elems.length ? elems : null;
    },
    // According to the className get the element (returned is a HTMLCollection)
    getElemsByClassName: function(className, root, tagName) {
        root = root || document; // The root node has no incoming, the default is document
        tagName = tagName || '*'; // No incoming label, the default for all tags
        var i = 0,
            classElements = [],
            elements = root.getElementsByTagName(tagName),
            elementsLen = elements.length;
            pattern = new RegExp('(^|\\s)' + className + '(\\s|$)'); // The className parameter is to search
        // The traversal of all elements, if the match to the incoming className, the corresponding element is added to the array
        for (; i <elementsLen; i++) {
            if (pattern.test(elements[i].className)) {
                classElements.push(elements[i]);
            }
        }
        return classElements; // Returns the set of matched elements
    },
    // According to name to obtain a set of elements
    getElemsByName: function(name) {
        var i, 
            elems = document.getElementsByName(name), // Native method (note the browser support)
            elemsLen,
            arr = [];
        return elems !== null && elems.length ? elems : null; // Return HTMLCollection
    },
    // Determine the style class exists
    hasClass: function(elem, className) {
        var reg = new RegExp("^|\\s" + className + "\\s|$");
        return reg.test(elem.className) ? true : false;
    }
};

/**
 * Simple CSS selector support #id,.ClassName, @formName, and tagName.className, node node five formats
 * @param {String || Object}
 * @param {Element} [root] Optional, from which the root node search
 * @return {object || HTMLCollection} A collection of individual elements or elements
 */
var $ = function(selector, root) {
    // Reuse variables
    var    i,
        elems,
        elemsLen,
        matchAry = [];

    // If the selector selector is empty, the termination of execution. 
    if (selector === undefined) {
        return; 
    // If the selector node or node list, directly returns. 
    } else if (dom.isNode(selector) || dom.isNodeList(selector)) {
        return selector;
    // If the selector for the window object, directly returns. 
    } else if (dom.isWindow(selector)) {
        return selector;
    }

    var selector = selector.toString();
    // Match "#id" case
    if (selector.indexOf('#') === 0) { 
        return dom.getElemByID(selector.substring(1));

    // Match ".ClassName" case
    } else if (selector.indexOf('.') === 0) {
        elems = dom.getElemsByClassName(selector.substring(1), root);

        if (elems.constructor && elems.constructor.toString().indexOf('Array') > -1) { // Judge elems array object
            matchAry = elems;
        } else {
            for (i = 0, elemsLen = elems.length; i <elemsLen; i++) {
                matchAry.push(elems[i]);
            }
        }

        return matchAry; // Returns the set of matched elements

    // Match "@name" case
    } else if (selector.indexOf('@') === 0) {
        elems = dom.getElemsByName(selector.substring(1));
        
        for (i = 0, elemsLen = elems.length; i <elemsLen; i++) {
            matchAry.push(elems[i]);
        }

        return matchAry; // Returns the set of matched elements

    // Match "tagName.className" case
    } else {
        if (selector.indexOf('.') > 0 && selector.indexOf('.') < selector.length) {
            // According to tagName to obtain a set of elements
            elems = dom.getElemsByTagName(selector.substring(0, selector.indexOf('.')), root);
            var    className = selector.substr(selector.indexOf('.') + 1);
            
            for (i = 0, elemsLen = elems.length; i <elemsLen; i++) {
                // If the element is matched to the className, the elements are added to the array in matchAry
                if (dom.hasClass(elems[i], className)) {
                    matchAry.push(elems[i]);
                }
            }        
        } else { // Or if not found ", the getElemsByTagName method is called."
            matchAry = dom.getElemsByTagName(selector, root);
        }

        return matchAry; // Returns the set of matched elements
    }
};

An instance of demo.:

The test results under firebug.:

Conclusion: Although the CSS selector and jQuery ratio is cannot withstand a single blow, especially in the implementation of skills, performance. But in the implement of the usual number of small projects or effect, for JS to obtain the page elements of the operation, the feeling is good enough, and not always rely on the framework to realize the interactive effect of some pages.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Nan at November 18, 2013 - 9:13 AM