如何像在jQuery中一样过滤vanilla Javascript中的元素?



例如,在jQuery中,如果我想要所有<div><p>元素,我会这样做:

var $x = $("p, div");

然后,如果我想要 x 中的所有<div>元素,那么我这样做:

var $divs = $x.filter("div");

那么如何在vanilla JavaScript中做这个简单的filter的事情呢?

例如,要选择所有<div><p>,那么我可以这样做:

var x = document.querySelectorAll("div, p");

但是vanilla JavaScript没有像jQuery那样的过滤功能,所以我不能这样做:

var divs = x.filter("div"); // ERROR

希望有人可以帮助我:-(

提前谢谢。

更新

一些评论/答案建议做一些类似.tagName == "DIV">来查找div,但是,我想要一个带有字符串选择器的解决方案,就像在 jQuery 中一样。

原因是因为我还想使用属性、类甚至多个选择器进行过滤,其中您输入逗号。字符串选择器必须是动态的。

这意味着,我不知道选择器中有什么。它可以是"div[foo='asd'], .bar" 或 "#hello, [xx='yy'], p">

所以我不能只硬编码 .tagName == "DIV",因为我不知道选择器字符串中有什么。

您可以使用matches函数来检查 CSS 选择器是否与给定元素匹配。

var x = document.querySelectorAll("div, p");
var divs = [];
// Iterate through the elements that the first query selector matched
//  (is a paragraph or a div tag)
for (var elem of x) {
// Check if the given element matches the second query selector
//  (is a div tag)
if (elem.matches('div')) {
divs.push(elem);
}
}

可以使用以下方法更简洁地编写此代码(并使用更现代的代码(:

let x = document.querySelectorAll("div, p");
let divs = Array.from(x).filter(elem => elem.matches("div"));

你可以使用 Array.filter

const elems = document.querySelectorAll('p, div');
const divs = [...elems].filter(e => {
return e.tagName == 'DIV'
});
console.log(divs)
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<p id="p1"></p>
<p id="p2"></p>
<p id="p3"></p>

您可以更改e.tagName以使用其他内容进行过滤:

const elems = document.querySelectorAll('p, div');
const divs = [...elems].filter(e => {
return e.tagName == 'DIV'
});
const byId = [...elems].filter(e => {
return e.id == 'div1'
});
const byClass = [...elems].filter(e => {
return e.className == 'class1'
});
console.log(byClass)
<div id="div1" class="class1"></div>
<div id="div2" class="class1"></div>
<div id="div3" class="class2"></div>
<p id="p1" class="class1"></p>
<p id="p2" class="class2"></p>
<p id="p3" class="class2"></p>

你可以将 Array.filter(( 与 Element.matches(( 结合使用

var x = document.querySelectorAll("div, p");
var divs = x.filter(y => y.matches("div"));
// for p tags
var paragraphs = x.filter(y => y.matches("p"));
//for both div and p tags
var mix = x.filter(y => y.matches("div, p"));

querySelectorAll 返回 NodeList 而不是数组。

您需要将其转换为数组

var arr = Array.prototype.slice.call(x);
var divs = arr.filter(el => { return el.tagName == 'DIV' });

一个非常幼稚的方法:

function get(selector) {
const els = document.querySelectorAll(selector);
return {
selector,
length: els.length,
get: i => els[i],
[Symbol.iterator]: () => els[Symbol.iterator](),
filter: f => get(selector + ", " + f)
};
}

可用作:

const menus = get(".menu");
for(const el of menus) console.log(el);
console.log(menus.filter("div").get(0));

最新更新