我的代码

(function (w) {
        var ver = '1.0';
        var doc = document;
        //var simple = /^(?:#|\.)?([\w-_]+)/;                         
        var r1 = /^(a|body|canvas|button|div|form|frame|frameset|h1|h2|h3|h4|h5|h6|iframe|img|input|li|object|p|span|table|th|tr|td|textarea|ul|video|script|\*)$/i;                         //\w 任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
        var r2 = /[^\w]+/;  //特殊字符 .#~()....    //\w 任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个


        function Q(query, context) {
            context = (context || doc);  //设定上下文            
            if (typeof (query) == 'object') {
                return filter2(context, query);       //暂未在上下文context中筛选
            }
            if (!r2.test(query) && !r1.test(query)) {   //没有特殊符号 且非关键字 (兼容以前旧的写法)
                return filter2(context, doc.getElementById(query));
            }


            //调用原生选择器
            if (context.querySelector && false) {  //querySelector   //querySelectorAll
                alert('原生选择器');
                return context.querySelector(query);
            } else {
                alert('自定义选择器');
                var ret = handle(query, context);
                if (!ret) {
                    return null;
                }
                if (IsArray(ret) || isCollection(ret)) {
                    return (ret.length > 0) ? ret[0] : null; //如是数组,返回第一个对象
                } else {
                    return ret;
                }
            }
        }


        //自定义选择器
        function handle(query, context) {
            var parts = query.replace(/\s+/g, " ").split(" ");      //分组:  \s    包括空格、制表符、换页符等空白字符的其中任意一个   \+相当于{1,}
            var part = parts.pop();                                 //筛选出最后一个  pop() 方法将删除数组的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。
            var s = Factory.create(part);                           //创建选择器对象 
            if (!s) { return null; }                                //如果创建选择器失败返回null
            var ret = s.find(context);
            //如有对象,从上下文context中查找 包含字符part的对象,[返回可能是对象,也可能是对象数组]
            if (parts[0] && ret) {     //有对象且还要待筛选项
                var ret2 = [];
                if (!IsArray(ret) && !isCollection(ret)) { ret = [ret]; } //单个对象
                for (var i = 0; i < ret.length; i++) {
                    if (filter(parts.slice(0), ret[i], ret[i], context)) { ret2.push(ret[i]); } //有匹配,加入返回列表
                }
                if (ret2.length > 0) { return ret2; } else { return null; }
            } else {
                return ret;
            }
        }
        function filter(parts, node, ret, context) {      //从上下文中逐级筛选    
            var part = parts.pop();                       //筛选出最后一个
            var s = Factory.create(part);                 //创建选择器对象
            if (!s) { return null; }                      //如果创建失败,返回null
            var selector = s.find(context);               //查询对象            
            if (!selector) { return null; }               //未找到对象返回null   
            if (!IsArray(selector) && !isCollection(selector)) { selector = [selector]; }  //初始化容器对象数组   
            for (var i = 0; i < selector.length; i++) { //只要有匹配的就直接返回 
                if (contains(selector[i], node)) {
                    if (parts[0]) {
                        if (filter(parts.slice(0), selector[i], ret, context)) {
                            return ret;
                        }
                    } else {
                        return ret;
                    }
                }
            }
            return null; //未找到返回null           
        }
        function filter2(p, node) {
            if (node) {
                var parent = node.parentNode;
                while (parent) {
                    if (parent == p) {
                        return node;
                    }
                    parent = parent.parentNode;
                }
            }
            return null;
        }
        //a包含b
        function contains(a, b) {
            if (b) {
                while ((b = b.parentNode)) {
                    if (b === a) {
                        return true;
                    }
                }
            }
            return false;
        };




        // contains = hasCompare || rnative.test(docElem.contains) ?
        // function (a, b) {
        //    var adown = a.nodeType === 9 ? a.documentElement : a,
        // bup = b && b.parentNode;
        //    return a === bup || !!(bup && bup.nodeType === 1 && (
        // adown.contains ?
        // adown.contains(bup) :
        // a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
        // ));
        // } :
        // function (a, b) {
        //    if (b) {
        //        while ((b = b.parentNode)) {
        //            if (b === a) {
        //                return true;
        //            }
        //        }
        //    }
        //    return false;
        // };




        //根据查询选择符创建相应选择器对象
        var Factory = {
            create: function (query) {
                if (IDSelector.test(query)) {
                    return new IDSelector(query);
                } else if (TagSelector.test(query)) {
                    return new TagSelector(query);
                } else if (ClassSelector.test(query)) {
                    return new ClassSelector(query);
                }
                return null;
            }
        };






        //ID选择器
        function IDSelector(id) {
            this.id = id.substring(1);
        }
        IDSelector.prototype = {
            find: function (context) {
                var ret = doc.getElementById(this.id);
                return (contains(context, ret) ? ret : null);
            },
            match: function (element) {
                return element.id == this.id;
            }
        };
        IDSelector.test = function (selector) {
            var regex = /^#([\w\-]+)$/;
            return regex.test(selector);
        };


        //元素选择器
        function TagSelector(tagName) {
            this.tagName = tagName.toUpperCase();
        }
        TagSelector.prototype = {
            find: function (context) {
                return context.getElementsByTagName(this.tagName);
            },
            match: function (element) {
                return this.tagName == element.tagName.toUpperCase() || this.tagName === "*";
            }
        };
        TagSelector.test = function (selector) {
            var regex = /^([\w\*\-]+)$/;
            return regex.test(selector);
        };


        //类选择器 如div.c1.c2 #Id.c1.c2
        function ClassSelector(className) {
            this.tagName = (className.replace(/^(#?[\w\-]+)?((\.[\w\-]+)+)$/, '$1') || '*');
            this.className = ('|' + className.replace(/^(#?[\w\-]+)?((\.[\w\-]+)+)$/, '$2').replace(/\./g, '|.|') + '|').split('.').slice(1);
        }
        ClassSelector.prototype = {
            find: function (context) {
                var s = Factory.create(this.tagName);
                if (!s) { return null; }         //创建失败返回null
                var elements = s.find(context);
                if (!elements) { return null; }  //未找到对象返回null                    
                var ret = [];                    //创建返回对象
                if (!IsArray(elements) && !isCollection(elements)) { elements = [elements]; }  //初始对象数组  
                for (var i = 0; i < elements.length; i++) {
                    if (this.match(elements[i])) {
                        ret.push(elements[i]);
                    }
                }
                if (ret.length < 1) { return null } else { return ret; }
            },
            match: function (element) {
                if (!element.className) { return false; }
                var className = this.className;
                var cname = ('|' + element.className.replace(/[ ]+/g, '|') + '|').replace(/\|+/g, '|');
                for (var i = 0; i < className.length; i++) {
                    if (cname.indexOf(className[i]) < 0) { //只要有不匹配的就返回false                     
                        return false;
                    }
                }
                return true;
            }


        };
        ClassSelector.test = function (selector) {
            var regex = /^(#?[\w\-]+)?((\.[\w\-]+)+)$/; //div.c1.c2 #Id.c1.c2
            return regex.test(selector);
        };


        //TODO:属性选择器
        function AttributeSelector(attr) {
            this.find = function (context) {
            };


            this.match = function (element) {
            };


        }
        AttributeSelector.test = function (selector) {
            var regex = /\[([\w\-_]+)(?:=([\w\-_]+))?\]/;
            return regex.test(selector);
        };
























        //是否数组
        function IsArray(o) {
            return Object.prototype.toString.call(o) === '[object Array]';
        }
        function isCollection(o) {
            if (o && o.length && !o.nodeType) {
                return true;
            } else {
                return false;
            }
            //return o.toString() == '[object HTMLCollection]';
        }






        w.$ || (w.$ = Q);
    })(window)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值