js 实现css风格选择器(压缩后2KB)


Posted in Javascript onJanuary 12, 2012

近日在做一些OA前端界面,为了更好管理页面代码想写个js选择器,写着写着发现很费力,索性在网上找找看,功夫不负有心人, 找到一个mini css选择器,且性能不凡:以下代码是压缩后的,仅2KB。

var $=(function(){var b=/(?:[\w\-\\.#]+)+(?:\[\w+?=([\'"])?(?:\\\1|.)+?\1\])?|\*|>/ig,g=/^(?:[\w\-_]+)?\.([\w\-_]+)/,f=/^(?:[\w\-_]+)?#([\w\-_]+)/,j=/^([\w\*\-_]+)/,h=[null,null];function d(o,m){m=m||document;var k=/^[\w\-_#]+$/.test(o);if(!k&&m.querySelectorAll){return c(m.querySelectorAll(o))}if(o.indexOf(",")>-1){var v=o.split(/,/g),t=[],s=0,r=v.length;for(;s<r;++s){t=t.concat(d(v[s],m))}return e(t)}var p=o.match(b),n=p.pop(),l=(n.match(f)||h)[1],u=!l&&(n.match(g)||h)[1],w=!l&&(n.match(j)||h)[1],q;if(u&&!w&&m.getElementsByClassName){q=c(m.getElementsByClassName(u))}else{q=!l&&c(m.getElementsByTagName(w||"*"));if(u){q=i(q,"className",RegExp("(^|\\s)"+u+"(\\s|$)"))}if(l){var x=m.getElementById(l);return x?[x]:[]}}return p[0]&&q[0]?a(p,q):q}function c(o){try{return Array.prototype.slice.call(o)}catch(n){var l=[],m=0,k=o.length;for(;m<k;++m){l[m]=o[m]}return l}}function a(w,p,n){var q=w.pop();if(q===">"){return a(w,p,true)}var s=[],k=-1,l=(q.match(f)||h)[1],t=!l&&(q.match(g)||h)[1],v=!l&&(q.match(j)||h)[1],u=-1,m,x,o;v=v&&v.toLowerCase();while((m=p[++u])){x=m.parentNode;do{o=!v||v==="*"||v===x.nodeName.toLowerCase();o=o&&(!l||x.id===l);o=o&&(!t||RegExp("(^|\\s)"+t+"(\\s|$)").test(x.className));if(n||o){break}}while((x=x.parentNode));if(o){s[++k]=m}}return w[0]&&s[0]?a(w,s):s}var e=(function(){var k=+new Date();var l=(function(){var m=1;return function(p){var o=p[k],n=m++;if(!o){p[k]=n;return true}return false}})();return function(m){var s=m.length,n=[],q=-1,o=0,p;for(;o<s;++o){p=m[o];if(l(p)){n[++q]=p}}k+=1;return n}})();function i(q,k,p){var m=-1,o,n=-1,l=[];while((o=q[++m])){if(p.test(o[k])){l[++n]=o}}return l}return d})();

把原版也分享下:
/** 
* "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
Javascript 相关文章推荐
Javascript 对象的解释
Nov 24 Javascript
Jquery中增加参数与Json转换代码
Nov 20 Javascript
Jquery ajax不能解析json对象,报Invalid JSON错误的原因和解决方法
Mar 27 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
May 30 Javascript
javascript的字符串按引用复制和传递,按值来比较介绍与应用
Dec 28 Javascript
jQuery实现可拖动的浮动层完整代码
May 27 Javascript
Javascript 函数的四种调用模式
Nov 05 Javascript
你不可不知的Vue.js列表渲染详解
Oct 01 Javascript
用js编写留言板
Mar 17 Javascript
js HTML DOM EventListener功能与用法实例分析
Apr 27 Javascript
JSON获取属性值方法代码实例
Jun 30 Javascript
Vue移动端项目实现使用手机预览调试操作
Jul 18 Javascript
js日历功能对象
Jan 12 #Javascript
关于 文本框默认值 的操作js代码
Jan 12 #Javascript
新发现一个骗链接的方法(js读取cookies)
Jan 11 #Javascript
JS读取cookies信息(记录用户名)
Jan 10 #Javascript
判断对象是否Window的实现代码
Jan 10 #Javascript
jQuery在IE下使用未闭合的xml代码创建元素时的Bug介绍
Jan 10 #Javascript
javascript中onmouse事件在div中失效问题的解决方法
Jan 09 #Javascript
You might like
建立文件交换功能的脚本(二)
2006/10/09 PHP
phpwind中的数据库操作类
2007/01/02 PHP
linux系统上支持php的 iconv()函数的方法
2011/10/01 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
2017/06/30 PHP
PHP 文件锁与进程锁的使用示例
2017/08/07 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
php 二维数组快速排序算法的实现代码
2017/10/17 PHP
jquery调用wcf并展示出数据的方法
2011/07/07 Javascript
IE6、IE7中获取Button元素的值的bug说明
2011/08/28 Javascript
关于javascript中dataset的问题小结
2015/11/16 Javascript
JS动态创建元素的两种方法
2016/04/20 Javascript
jQuery解析返回的xml和json方法详解
2017/01/05 Javascript
JavaScript常见JSON操作实例分析
2018/08/08 Javascript
利用Node.js如何实现文件循环覆写
2019/04/05 Javascript
vue中使用element组件时事件想要传递其他参数的问题
2019/09/18 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
Vue实现todo应用的示例
2021/02/20 Vue.js
[59:26]DOTA2上海特级锦标赛D组资格赛#1 EG VS VP第二局
2016/02/28 DOTA
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
python Selenium 库的使用技巧
2020/10/16 Python
CSS3 中filter(滤镜)属性使用详解
2020/04/07 HTML / CSS
伦敦最有品味的百货:Liberty London
2016/11/12 全球购物
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
linux面试题参考答案(8)
2015/08/11 面试题
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
高考自主招生自荐信
2013/10/20 职场文书
入党积极分子介绍信
2014/01/17 职场文书
大三学生做职业规划:给未来找个方向
2014/02/24 职场文书
市场营销工作计划书
2014/09/15 职场文书
党的群众路线教育实践活动个人对照检查材料(四风)
2014/11/05 职场文书
2015年元旦主持词结束语
2014/12/14 职场文书
甲午风云观后感
2015/06/02 职场文书
适合毕业生创业的项目怎么找?
2019/08/08 职场文书
基于python的matplotlib制作双Y轴图
2021/04/20 Python
Python实现查询剪贴板自动匹配信息的思路详解
2021/07/09 Python
Python的代理类实现,控制访问和修改属性的权限你都了解吗
2022/03/21 Python