例如,在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));