?
? is() 根据选择器、元素或 jQuery 对象来检测匹配元素集合,如果这些元素中至少有一个元素匹配给定的参数,则返回 true。
它产用是Sizzle技术。
? 那我们如何使用querySelector模仿呢?
? 由于querySelector只能查找dom以下的DOM,所以我考虑到将采用dom的父dom来使用querySelector
? 由于querySelector无法查找精确子DOM(它将会查找其所有的子孙DOM),而且,要查找的dom可能会有很多兄弟
? 所以要重新定位到要查找的dom就有困难了,这时,我又想到id,由于在HTML中我们会规范,界面中需要唯一的ID
? 有了以上的条件,JQuery.is的模拟就有可能了,直接上代码
第一种方案:
?
var tagTokenRe = /^(#)?([\w\\-\\*]+)/;
function is(dom, selector) {
var tokenMatch = selector.match(tagTokenRe);
if (tokenMatch) {
if (tokenMatch[1] == "#") {
if (dom.id != tokenMatch[2]) {
return false;
}
} else {
if (dom.tagName.toLowerCase() != tokenMatch[2].toLowerCase()) {
return false;
}
}
selector = selector.replace(tokenMatch[0], "");
if (!selector) return true;
}
var pdom;
if (dom && (pdom = dom['parentNode'])) {
var id = dom.id;
if (!id) {
dom.id = id = "_J" + ++$.guid;
}
selector = '#' + id + selector;
var ret = pdom.querySelector(selector);
return ret !== null;
}
return false;
}
?以上缺点是要保障子dom的兄弟不能有相同的ID
?为了保障,可以将
?
var id = dom.id;
if (!id) {
dom.id = id = "_J" + ++$.guid;
}
selector = '#' + id + selector;
var ret = pdom.querySelector(selector);
改为第二种方案
?
var id = dom.id;
dom.id = '_JIS_'
selector = '#' + dom.id + selector;
var ret = pdom.querySelector(selector);
dom.id = id?id:null;
这样就可以保证ID的唯一性,但会降低性能。
?
?
?
?
第三种方案,采用存JS实现的如下:
?
var modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
tagTokenRe = /^(#)?([\w\\-\\*]+)/,
tplRe = /\{(\d+)\}/g,
cache = {};
var matchers = [
{re: /^\.([\w-]+)/, select: 'n = byClassName(n, " {1} ");if(n.length==0) return false;\n'},
{re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, select: 'n = byPseudo(n, "{1}", "{2}");if(n.length==0)return false;\n'},
{re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/, select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");if(n.length==0) return false;\n'},
{re: /^#([\w-]+)/, select: 'n = byId(n, "{1}");if(n.length==0) return false;\n'}
];
var operators = {
"=": function (a, v) {
return a == v;
}, "!=": function (a, v) {
return a != v;
}, "^=": function (a, v) {
return a && a.substr(0, v.length) == v;
}, "$=": function (a, v) {
return a && a.substr(a.length - v.length) == v;
}, "*=": function (a, v) {
return a && a.indexOf(v) !== -1;
}, "%=": function (a, v) {
return (a % v) == 0;
}, "|=": function (a, v) {
return a && (a == v || a.substr(0, v.length + 1) == v + '-');
}, "~=": function (a, v) {
return a && (' ' + a + ' ').indexOf(' ' + v + ' ') != -1;
}
};
var pseudos = {
"contains": function (c, v) {
var r = [], ri = -1;
for (var i = 0, ci; ci = c[i]; i++) {
if ((ci.textContent || ci.innerText || '').indexOf(v) != -1) {
r[++ri] = ci;
}
}
return r;
},
"checked": function (c) {
var r = [], 