把原版也分享下: 复制代码 代码如下: /** * "mini" Selector Engine * Copyright (c) 2009 James Padolsey * ------------------------------------------------------- * Dual licensed under the MIT and GPL licenses. * - http://www.opensource.org/licenses/mit-license.php * - http://www.gnu.org/copyleft/gpl.html * ------------------------------------------------------- * Version: 0.01 (BETA) */ var mini = (function(){ var snack = /(?:[w-\.#]+)+(?:[w+?=([""])?(?:\1|.)+?1])?|*|>/ig, exprClassName = /^(?:[w-_]+)?.([w-_]+)/, exprId = /^(?:[w-_]+)?#([w-_]+)/, exprNodeName = /^([w*-_]+)/, na = [null,null]; function _find(selector, context) { /** * This is what you call via x() 这是你们所谓的经x * Starts everything off... 开始上所有的 */ context = context || document; var simple = /^[w-_#]+$/.test(selector); if (!simple && context.querySelectorAll) { return realArray(context.querySelectorAll(selector)); } if (selector.indexOf(",") > -1) { var split = selector.split(/,/g), ret = [], sIndex = 0, len = split.length; for(; sIndex < len; ++sIndex) { ret = ret.concat( _find(split[sIndex], context) ); } return unique(ret); } var parts = selector.match(snack), part = parts.pop(), id = (part.match(exprId) || na)[1], className = !id && (part.match(exprClassName) || na)[1], nodeName = !id && (part.match(exprNodeName) || na)[1], collection; if (className && !nodeName && context.getElementsByClassName) { collection = realArray(context.getElementsByClassName(className)); } else { collection = !id && realArray(context.getElementsByTagName(nodeName || "*")); if (className) { collection = filterByAttr(collection, "className", RegExp("(^|\s)" + className + "(\s|$)")); } if (id) { var byId = context.getElementById(id); return byId?[byId]:[]; } } return parts[0] && collection[0] ? filterParents(parts, collection) : collection; } function realArray(c) { /** * Transforms a node collection into 转换一个节点收藏 * a real array 一个真正的阵列 */ try { return Array.prototype.slice.call(c); } catch(e) { var ret = [], i = 0, len = c.length; for (; i < len; ++i) { ret[i] = c[i]; } return ret; } } function filterParents(selectorParts, collection, direct) { /** * This is where the magic happens. 这就是魔法发生 * Parents are stepped through (upwards) to 父母们加紧通过向上 * see if they comply with the selector. 看看他们是否符合选择器 */ var parentSelector = selectorParts.pop(); if (parentSelector === ">") { return filterParents(selectorParts, collection, true); } var ret = [], r = -1, id = (parentSelector.match(exprId) || na)[1], className = !id && (parentSelector.match(exprClassName) || na)[1], nodeName = !id && (parentSelector.match(exprNodeName) || na)[1], cIndex = -1, node, parent, matches; nodeName = nodeName && nodeName.toLowerCase(); while ( (node = collection[++cIndex]) ) { parent = node.parentNode; do { matches = !nodeName || nodeName === "*" || nodeName === parent.nodeName.toLowerCase(); matches = matches && (!id || parent.id === id); matches = matches && (!className || RegExp("(^|\s)" + className + "(\s|$)").test(parent.className)); if (direct || matches) { break; } } while ( (parent = parent.parentNode) ); if (matches) { ret[++r] = node; } } return selectorParts[0] && ret[0] ? filterParents(selectorParts, ret) : ret; } var unique = (function(){ var uid = +new Date(); var data = (function(){ var n = 1; return function(elem) { var cacheIndex = elem[uid], nextCacheIndex = n++; if(!cacheIndex) { elem[uid] = nextCacheIndex; return true; } return false; }; })(); return function(arr) { /** * Returns a unique array返回一个独特的阵列 */ var length = arr.length, ret = [], r = -1, i = 0, item; for (; i < length; ++i) { item = arr[i]; if (data(item)) { ret[++r] = item; } } uid += 1; return ret; }; })(); function filterByAttr(collection, attr, regex) { /** * Filters a collection by an attribute. 一个收集过滤器一个属性 */ var i = -1, node, r = -1, ret = []; while ( (node = collection[++i]) ) { if (regex.test(node[attr])) { ret[++r] = node; } } return ret; } return _find; })();
以上代码支持css风格样式写法包括: 复制代码 代码如下: div .example body div div, p div, p, .example div p div > p div.example ul .example #title h1#title div #title ul.foo > * span