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

近日在做一些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"){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

把原版也分享下:

/**

* "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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值