<!doctype html> <html> <head> <title>aiQuery test</title> <script type="text/javascript"> /** * aiQuery * @author ouxingzhi */ void function (window, document, undefined) { var location = window.location, Slice = [].slice, RegTrim = /(?:^s+|s+$)/, RegBlank = /s+/, RegOperate = /s*(?:s|>|+|~(?!=))s*/i, RegElement = /^([w-]+|*)?(?:#([w-]+))?(?:.([w-]+))?(?:[([w-]+)(?:([~|^|$|*||]?=)['"]?([w-]+)['"]?)?])?(?::([w-]+(?:([w-]+))?))?$/i; function AIQuery(Selector, Content) { Selector = Selector.replace(RegTrim, ''); Content = Content || document; if (Content.querySelectorAll) { return Slice.call(Content.querySelectorAll(Selector)); } else { return querySelectorAll(Selector, Content) } } function querySelectorAll(Selector, Content) { var Groups = Selector.split(/s*\,s*/img), Results = []; for (var i = 0, len = Groups.length; i < len; i++) { Results = Results.concat(Find(Groups[i], Content)) } return Results } function Find(Selector, Content) { var Results = [], atoms = Selector.split(RegOperate), operates = Selector.match(RegOperate); operates = operates || []; for (var i = 0, len = operates.length; i < len; i++) (operates[i] = /^s+$/.test(operates[i]) ? ' ' : operates[i].replace(RegTrim, '')); var Results = EachTo(' ', atoms.shift(), operates, atoms, Content); return Results } function EachTo(op, at, operates, atoms, Content) { var Results = [], Median = [], operate, atom; if (Content.constructor === Array || 'length' in Content) { for (var i = 0, len = Content.length; i < len; i++) { Results = Results.concat(EachTo(op, at, operates.slice(0), atoms.slice(0), Content[i])) } } else if (Content.constructor === String) { Content = Find(Content, document); Results.concat(EachTo(op, at, operates.slice(0), atoms.slice(0), Content[i])) } else { Median = GetElementByAny(op, at, Content); if (Median) { if (operates && operates.length && atoms && atoms.length) { Results = EachTo(operates.shift(), atoms.shift(), operates, atoms, Median) } else { Results = Median } } } return Results } function GetElementByAny(op, at, Content) { if (typeof OperateFunction[op] !== 'undefined') { return OperateFunction[op](at, Content) } } var OperateFunction = { ' ': function (at, Content) { var einfo = buildElementInfo(at), preNodes = []; if (!einfo) return []; if (einfo.Id) { preNodes = document.getElementById(einfo.Id); preNodes = preNodes ? [preNodes] : [] } else if (einfo.ClassName && Content.getElementsByClassName) { preNodes = Content.getElementsByClassName(einfo.ClassName); preNodes = preNodes || [] } else if (einfo.TagName && Content.getElementsByTagName) { preNodes = Content.getElementsByTagName(einfo.TagName); preNodes = preNodes || [] } else { preNodes = Content.getElementsByTagName('*'); preNodes = preNodes || [] }; return filterNode(einfo, preNodes) }, '>': function (at, Content) { var einfo = buildElementInfo(at); preNodes = Content.childNodes || []; if (!einfo) return []; return filterNode(einfo, preNodes) }, '+': function (at, Content) { if (Content === document) return []; var einfo = buildElementInfo(at); if (!einfo) return []; var results = [], preNodes = (function () { var nextNode = Content.nextSibling; while (nextNode && nextNode.nodeType != 1) { nextNode = nextNode.nextSibling } return nextNode })(); preNodes = preNodes ? [preNodes] : []; if (preNodes.length) { results = filterNode(einfo, preNodes) } else { results = [] } return results }, '~': function (at, Content) { if (Content === document) return []; var einfo = buildElementInfo(at), preNodes = []; if (!einfo) return []; var sibling = Content.parentNode ? Content.parentNode.childNodes : null; if (sibling) { for (var i = 0, len = sibling.length; i < len; i++) if (Content !== sibling[i]) preNodes.push(sibling[i]) } return filterNode(einfo, preNodes) } }; function buildElementInfo(at) { var Einfo = RegElement.exec(at); if (!Einfo) return; return { TagName: Einfo[1] || undefined, Id: Einfo[2] || undefined, ClassName: Einfo[3] || undefined, AttrName: Einfo[4] || undefined, AttrOper: Einfo[5] || undefined, AttrVal: Einfo[6] || undefined, FakeClass: Einfo[7] || undefined } } function filterNode(Einfo, Nodes) { var results = [], RegClassName, isMatch; if (Einfo.ClassName) RegClassName = new RegExp('\b' + Einfo.ClassName + '\b', 'i'); for (var i = 0, len = Nodes.length; i < len; i++) { isMatch = true; if (Einfo.TagName !== undefined && Einfo.TagName.toUpperCase() !== Nodes[i].nodeName) isMatch = false; if (Einfo.Id !== undefined && Einfo.Id !== Nodes[i].id) isMatch = false; if (Einfo.ClassName !== undefined && !Nodes[i].className.match(RegClassName)) isMatch = false; isMatch = isMatchAttribute(Einfo, Nodes[i], isMatch); isMatch = isMatchFakeClass(Einfo, Nodes[i], isMatch); if (isMatch) results.push(Nodes[i]) } return results } function isMatchAttribute(Einfo, node, isMatch) { if (Einfo.AttrName === undefined && Einfo.AttrOper === undefined && Einfo.AttrVal === undefined) { } else if (Einfo.AttrName !== undefined && Einfo.AttrOper === undefined && Einfo.AttrVal === undefined && node.getAttribute && node.getAttribute(Einfo.AttrName) !== null) { isMatch = true } else if (Einfo.AttrName !== undefined && Einfo.AttrOper !== undefined && Einfo.AttrVal !== undefined && node.getAttribute) { switch (Einfo.AttrOper) { case '=': isMatch = node.getAttribute(Einfo.AttrName) === Einfo.AttrVal; break; case '~=': isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('(?:^|\s+)' + Einfo.AttrVal + '(?:$|\s+)', 'i'))); break; case '^=': isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('^' + Einfo.AttrVal, 'i'))); break; case '$=': isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp(Einfo.AttrVal + '$', 'i'))); break; case '*=': isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp(Einfo.AttrVal, 'i'))); break; case '|=': isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('(?:^|\-)' + Einfo.AttrVal + '(?:$|\-)', 'i'))); break } } return isMatch } function isMatchFakeClass(Einfo, node, isMatch) { if (Einfo.FakeClass === undefined) { } else { switch (Einfo.FakeClass) { case 'empty': isMatch = node.innerHTML.replace(RegTrim, '').length == 0; break; case 'checked': if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.checked; break; case 'enabled': if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.disabled; break; case 'disabled': if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.disabled; break; case 'target': var hash = location.hash.replace('#', ''); isMatch = hash === node.id || (node.name && hash === node.name); break } } return isMatch } window['aiQuery'] = AIQuery; } (window, document); </script> </head> <body> <div class="aaa"> <div class="bbb"> <label> 用户名:</label> <input type="text" id="username" /> </div> <pre> //使用方法 alert(aiQuery('.aaa .bbb [type=text]')); alert(aiQuery('.aaa label + input')); alert(aiQuery('#username')); </pre> </div> <script type="text/javascript"> alert(aiQuery('.aaa .bbb [type=text]')); alert(aiQuery('.aaa label + input')); alert(aiQuery('#username')); </script> </body> </html>