当前位置: 代码迷 >> Web前端 >> 打包选择器
  详细解决方案

打包选择器

热度:156   发布时间:2012-10-30 16:13:36.0
封装选择器
平时写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;
    }

})();
  相关解决方案