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 单例/单体模式(Singleton)
Apr 07 Javascript
浅析webapp框架AngularUI的demo
Dec 21 Javascript
javascript中Date对象的getDay方法使用指南
Dec 22 Javascript
jQuery 遍历函数详解
Jul 05 Javascript
js实现千分符和保留几位小数的简单实例
Aug 01 Javascript
购物车前端开发(jQuery和bootstrap3)
Aug 27 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
Sep 04 Javascript
jQuery使用Layer弹出层插件闪退问题
Dec 22 Javascript
react-native 封装选择弹出框示例(试用ios&amp;android)
Jul 11 Javascript
浅谈angular4 ng-content 中隐藏的内容
Aug 18 Javascript
React从react-router路由上做登陆验证控制的方法
May 10 Javascript
layui监听下拉选框选中值变化的方法(包含监听普通下拉选框)
Sep 24 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
咖啡豆要不要放冰箱的原因
2021/03/04 冲泡冲煮
深入解析PHP中逗号与点号的区别
2013/08/05 PHP
php Session存储到Redis的方法
2013/11/04 PHP
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
2007/03/24 Javascript
整理8个很棒的 jQuery 倒计时插件和教程
2011/12/12 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
jquery创建表格(自动增加表格)代码分享
2013/12/25 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
vue2.0数据双向绑定与表单bootstrap+vue组件
2017/02/27 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
JavaScript之class继承_动力节点Java学院整理
2017/07/03 Javascript
React Native之TextInput组件解析示例
2017/08/22 Javascript
React中如何引入Angular组件详解
2018/08/09 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
对 Vue-Router 进行单元测试的方法
2018/11/05 Javascript
Vue加载json文件的方法简单示例
2019/01/28 Javascript
[02:06]DOTA2英雄基础教程 暗影萨满
2013/12/16 DOTA
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
python 实现堆排序算法代码
2012/06/05 Python
Python中的super用法详解
2015/05/28 Python
查看Django和flask版本的方法
2018/05/14 Python
Python 3.6 -win64环境安装PIL模块的教程
2019/06/20 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
Django框架ORM数据库操作实例详解
2019/11/07 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
Django关于admin的使用技巧和知识点
2020/02/10 Python
Python的collections模块真的很好用
2021/03/01 Python
明信片寄语大全
2014/04/08 职场文书
摄影专业毕业生求职信
2014/08/05 职场文书
大雁塔导游词
2015/02/04 职场文书
怎样写辞职信
2015/02/27 职场文书
2016教师学习党章心得体会
2016/01/15 职场文书
《为人民服务》教学反思
2016/02/20 职场文书
2020年元旦晚会策划书模板
2019/12/30 职场文书
JavaScript数组 几个常用方法总结
2021/11/11 Javascript
Windows7下FTP搭建图文教程
2022/08/05 Servers