读书人

打包选择器

发布时间: 2012-10-30 16:13:36 作者: rapoo

封装选择器
平时写js,用到选择器是必不可少的,一直用框架的选择器,内部到底是怎么样的呢

(function(){    var doc = document,        REG_ID = /^#[\w-]+$/,        REG_QUERY = /^(:?#([\w-]+))?\s*([\w-]+|\*)?\.?([\w-]+)?$/;    //将封装好的默认函数在进行集中处理,用正则来区分传入的selector    function query(selector,content){        var match, ret = [], id, tag, cls ,t;        content = tuneContent(content);        if(isString(selector)){            selector = trim(selector);    //如果传入的是id,那么就直接用封装好的getElementById            if(REG_ID.test(selector)){                t = getElementById(selector.slice(1),content);                if(t) ret = [t];//返回数组    //exec返回第一个匹配的字符串,和所有分组的反向引用(即正则中括号包裹的部分)            }else if((match = REG_QUERY.exec(selector))){                id = match[1];                tag = match[2];                cls = match[3];//如果获取到的反向引用中有id,那么将content设为根据id获取到的元素,                //否则仍旧为tuneContent调整后的值                if(content = id ? getElementById(id,content) : content){//如果有class                    if(cls){//如果没有id并且传入的selector参数中有空格,即排除#id.cls                        if(!id && selector.indexOf(" ") !== -1){//那么使用封装好的getElementsByClassName来获取元素                            ret = getElementsByClassName(cls,tag,content);                        }else{         //处理#id.cls 这个selector参数应该表示的是#id并且这个id的className值为cls//那么先根据id取到元素,在判断取到的这个元素的className是否含有cls                            t = getElementById(id,content);                            if(t && hacClass(t,cls)){                                ret = [t];                            }                        }                    }else if(tag){//如果有tag       //那么直接用原生的getElementsByTagName来获取元素                        ret = content.getElementsByTagName(tag);                    }                }            }        }        return ret;    }    function get(){        return query(selector,content)[0];    }    //将content调整到一个合理的值    function tuneContent(content){//如果content未定义,那么content=doc        if(content === undefined){            content = doc;//如果content是个id,那么content=根据id获取到元素        }else if(isString(content) && REG_ID.test(content)){            content = getElementById(content.slice(1),doc);//如果content即不是元素或者不是doc文档类型,那么content=null        }else if(content && content.nodeType !== 1 && content.nodeType !==9){            content = null;        }        return content;    }//封装默认的getElementById函数    function getElementById(el,content){        if(content.nodeType !== 9){            content = content.ownerDocument;        }        return content.getElementById(el);    }//封装默认的getElementsByClassName函数(高级浏览器才有这个默认函数)    function getElementsByClassName(cls,tag,content){        if(!cls) return;        var els = content.getElementsByClassName(cls),            ret = els,j=0;//根据传入的tag筛选获取到的元素        if(tag && tag != "*"){            ret = [];            for(var i = 0,len = els.length;i<len;i++){                el = els[i];                if(el.tagName == tag.toUpperCase()){                    ret[j++] = el;                }            }        }        return ret;    }//如果不支持getElementsByClassName,则降级使用querySelectorAll,//再不支持,则先根据tag获取到元素,在遍历这些元素,看这些元素的className是否含有传入的className值    if(!doc.getElementsByClassName){        if(doc.querySelectorAll){            getElementsByClassName = function(cls,tag,content){                return content.querySelectorAll((tag ? tag : "") +"." + cls);            }        }else{            getElementsByClassName = function(cls,tag,content){                var els = content.getElementsByTagName(tag),                    ret = [],j=0,cls = " "+cls+" ";                for(var i = 0,len = els.length;i<len;i++){                    var el = els[i],t = el.className;                    if(t && hasClass(el,cls)){                        ret[j++] = el;                    }                }                return ret;            }        }    }    function isString(str){        return str && typeof str === "string";    }    function trim(str){        return str.replace(/(^\s*)|(\s*$)/g,"");    }    //不支持多个cls同时判断    function hasClass(el,cls){        var cls = " " + cls + " ",            elcls = " " + el.className + " ";        return elcls.indexOf(cls) > -1;    }})();

读书人网 >Web前端

热点推荐