javascript 如何过滤 QuerySelectorAll 返回的元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6791112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:53:23  来源:igfitidea点击:

How to filter elements returned by QuerySelectorAll

javascript

提问by timw4mail

I'm working on a javascript libarary, and I use this function to match elements:

我正在开发一个 javascript 库,我使用这个函数来匹配元素:

$ = 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;
};

There are occasions where I would want to filter the result of this function, like pick out a div span, or a #id divor some other fairly simple selector.

有时我想过滤这个函数的结果,比如选择 a div span,或 a#id div或其他一些相当简单的选择器。

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?

如何过滤这些结果?我可以创建一个文档片段,并在该片段上使用 querySelectorAll 方法,还是必须求助于手动字符串操作?

I only care about modern browsers, and IE8+.

我只关心现代浏览器和 IE8+。

If you want to look at the rest of my library, it's here: https://github.com/timw4mail/kis-js

如果你想看看我图书馆的其余部分,它在这里:https: //github.com/timw4mail/kis-js

Edit:

编辑:

To clarify, I want to be able to do something like $_(selector).children(other_selector) and return the children elements matching that selector.

澄清一下,我希望能够执行诸如 $_(selector).children(other_selector) 之类的操作并返回与该选择器匹配的子元素。

Edit:

编辑:

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;

}

It takes a tag like div, an id, or a class selector, and returns the matching elements with the curr_selargument.

它接受像div、id 或类选择器这样的标签,并返回带有curr_sel参数的匹配元素。

I don't want to have to resort to a full selector engine, so is there a better way?

我不想求助于完整的选择器引擎,那么有更好的方法吗?

回答by jAndy

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 spanor even better #id div, those results are already filtered, no ?

我不认为我的问题是正确的。你为什么要“过滤”querySelectorAll()实际上是某种过滤器本身的结果。如果您查询div span甚至更好#id div,这些结果已经被过滤了,不是吗?

However, you can apply Array.prototype.filterto the static result of querySelectorAlllike follows:

但是,您可以应用Array.prototype.filterquerySelectorAll类似如下的静态结果:

var filter   = Array.prototype.filter,
    result   = document.querySelectorAll('div'),
    filtered = filter.call( result, function( node ) {
        return !!node.querySelectorAll('span').length;
    });

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)

该代码将首先用于querySelectorAll()查询<div>文档中的所有节点。之后它将过滤<div>包含至少一个<span>. 该代码没有多大意义,仅用于演示目的(以防万一某些 SO 成员想要创建一个唐克评论)

update

更新

You can also filter with Element.compareDocumentPosition. I'll also tell if Elements are disconnected, following, preceding, or contained. See MDC .compareDocumentPosition()

您还可以使用 过滤Element.compareDocumentPosition。我还会告诉如果元素disconnectedfollowingpreceding,或contained。见MDC .compareDocumentPosition()

回答by lasec0203

Note: NodeList is not a genuine array, that is to say it doesn't have the array methods like slice, some, map etc. To convert it into an array, try Array.from(nodeList).

注意:NodeList 不是真正的数组,也就是说它没有slice、some、map 等数组方法。要转换成数组,可以试试Array.from(nodeList)。

ref: https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll

参考:https: //developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll

for example:

例如:

let highlightedItems = Array.from(userList.querySelectorAll(".highlighted"));

highlightedItems.filter((item) => {
 //...
})

回答by Scott Weaver

Most concise way in 2019 is with spread syntax...plus an array literal [...], which work great with iterable objects like the NodeList returned by querySelectorAll:

2019 年最简洁的方法是使用扩展语法...加上数组文字[...],它适用于可迭代对象,例如由 返回的 NodeList querySelectorAll

[...document.querySelectorAll(".myClass")].filter(el=>{/*your code here*/})

[...document.querySelectorAll(".myClass")].filter(el=>{/*your code here*/})

回答by user113716

Some browsers that support qsaalso support a non-standard matchesSelectormethod, like:

一些支持的浏览器qsa也支持非标准matchesSelector方法,例如:

element.webkitMatchesSelector('.someSelector')

...that will return a boolean representing whether elementmatched the selector provided. So you could iterate the collection, and apply that method, retaining positive results.

...这将返回一个布尔值,表示是否element与提供的选择器匹配。所以你可以迭代集合,并应用该方法,保留积极的结果。

In browsers that don't have a matchesSelector, you'd probably need to build your own selector based method similar to the selector engine you're building.

在没有 的浏览器中matchesSelector,您可能需要构建自己的基于选择器的方法,类似于您正在构建的选择器引擎。