如何过滤QuerySelectorAll返回的元素 [英] How to filter elements returned by QuerySelectorAll
问题描述
我正在使用javascript库,并且使用此函数来匹配元素:
I'm working on a javascript libarary, and I use this function to match elements:
$ = function (a)
{
var x;
if (typeof a !== "string" || typeof a === "undefined"){ return a;}
//Pick the quickest method for each kind of selector
if(a.match(/^#([\w\-]+$)/))
{
return document.getElementById(a.split('#')[1]);
}
else if(a.match(/^([\w\-]+)$/))
{
x = document.getElementsByTagName(a);
}
else
{
x = document.querySelectorAll(a);
}
//Return the single object if applicable
return (x.length === 1) ? x[0] : x;
};
在某些情况下,我想过滤此函数的结果,例如选择 div span
或 #id div
或其他一些相当简单的选择器.
There are occasions where I would want to filter the result of this function, like pick out a div span
, or a #id div
or some other fairly simple selector.
如何过滤这些结果?我可以创建文档片段,并在该片段上使用querySelectorAll方法,还是必须诉诸于手动字符串操作?
How can I filter these results? Can I create a document fragement, and use the querySelectorAll method on that fragment, or do I have to resort to manual string manipulation?
我只关心现代浏览器和IE8 +.
I only care about modern browsers, and IE8+.
如果要查看我的库的其余部分,请访问: https://github.com/timw4mail/kis-js
If you want to look at the rest of my library, it's here: https://github.com/timw4mail/kis-js
为澄清起见,我希望能够执行类似$ _(selector).children(other_selector)的操作,并返回与该选择器匹配的子元素.
To clarify, I want to be able to do something like $_(selector).children(other_selector) and return the children elements matching that selector.
因此,这是最简单选择器的潜在解决方案:
So here's my potential solution to the simplest selectors:
tag_reg = /^([\w\-]+)$/;
id_reg = /#([\w\-]+$)/;
class_reg = /\.([\w\-]+)$/;
function _sel_filter(filter, curr_sel)
{
var i,
len = curr_sel.length,
matches = [];
if(typeof filter !== "string")
{
return filter;
}
//Filter by tag
if(filter.match(tag_reg))
{
for(i=0;i<len;i++)
{
if(curr_sell[i].tagName.toLowerCase() == filter.toLowerCase())
{
matches.push(curr_sel[i]);
}
}
}
else if(filter.match(class_reg))
{
for(i=0;i<len;i++)
{
if(curr_sel[i].classList.contains(filter))
{
matches.push(curr_sel[i]);
}
}
}
else if(filter.match(id_reg))
{
return document.getElementById(filter);
}
else
{
console.log(filter+" is not a valid filter");
}
return (matches.length === 1) ? matches[0] : matches;
}
它接受一个像 div
这样的标签,一个id或一个类选择器,并返回带有 curr_sel
参数的匹配元素.
It takes a tag like div
, an id, or a class selector, and returns the matching elements with the curr_sel
argument.
我不想诉诸于全选择器引擎,那么有没有更好的方法呢?
I don't want to have to resort to a full selector engine, so is there a better way?
推荐答案
我认为我的问题不对.您为什么要过滤" querySelectorAll()
的结果,实际上它本身就是某种过滤器.如果您查询 div span
甚至更好的 #id div
,则这些结果已被过滤,不是吗?
I don't think I get the question right. Why would you want to "filter" the result of querySelectorAll()
which infact, is some kind of a filter itself. If you query for div span
or even better #id div
, those results are already filtered, no ?
但是,您可以将 Array.prototype.filter
应用于 querySelectorAll
的静态结果,如下所示:
However, you can apply Array.prototype.filter
to the static result of querySelectorAll
like follows:
var filter = Array.prototype.filter,
result = document.querySelectorAll('div'),
filtered = filter.call( result, function( node ) {
return !!node.querySelectorAll('span').length;
});
该代码将首先使用 querySelectorAll()
来查询文档中的所有< div>
节点.之后,它将过滤包含至少一个&span>
的< div>
节点.该代码没有多大意义,仅用于说明目的(以防万一某个SO成员想要创建donk注释)
That code would first use querySelectorAll()
to query for all <div>
nodes within the document. Afterwards it'll filter for <div>
nodes which contain at least one <span>
. That code doesn't make much sense and is just for demonstrative purposes (just in case some SO member wants to create a donk comment)
更新
您还可以使用 Element.compareDocumentPosition
进行过滤.我还将告诉您元素是 disconnected
, following
, preced
还是 contained
.参见 MDC .compareDocumentPosition()
You can also filter with Element.compareDocumentPosition
. I'll also tell if Elements are disconnected
, following
, preceding
, or contained
. See MDC .compareDocumentPosition()
这篇关于如何过滤QuerySelectorAll返回的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!