最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to filter elements in vanilla Javascript like in jQuery? - Stack Overflow

programmeradmin3浏览0评论

For example, in jQuery, if i want all <div> and <p> elements, I do this:

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

And then if i want all the <div> elements in x, then I do this:

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

So how do i do this simple filter thing in vanilla JavaScript?

For example, to select all <div> and <p>, then I can do this:

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

But vanilla JavaScript doesn't have the filter function like in jQuery, so I can't do this:

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

Hope someone can help me with this :-)

Thanks in advance.

UPDATE

Some ments/answers have suggested to do something like .tagName == "DIV" to find the divs, however, i want a solution with a string selector like in jQuery.

The reason is because i also want to filter with attributes, classes and even multiple selectors where you put in ma. And the string selector must be dynamic.

That means, i dont know whats in the selector. It could be "div[foo='asd'], .bar" or "#hello, [xx='yy'], p"

So i cant just hardcode the .tagName == "DIV", beacuse i dont know whats in the selector string.

For example, in jQuery, if i want all <div> and <p> elements, I do this:

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

And then if i want all the <div> elements in x, then I do this:

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

So how do i do this simple filter thing in vanilla JavaScript?

For example, to select all <div> and <p>, then I can do this:

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

But vanilla JavaScript doesn't have the filter function like in jQuery, so I can't do this:

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

Hope someone can help me with this :-)

Thanks in advance.

UPDATE

Some ments/answers have suggested to do something like .tagName == "DIV" to find the divs, however, i want a solution with a string selector like in jQuery.

The reason is because i also want to filter with attributes, classes and even multiple selectors where you put in ma. And the string selector must be dynamic.

That means, i dont know whats in the selector. It could be "div[foo='asd'], .bar" or "#hello, [xx='yy'], p"

So i cant just hardcode the .tagName == "DIV", beacuse i dont know whats in the selector string.

Share Improve this question edited May 29, 2018 at 20:41 Assassinbeast asked May 29, 2018 at 20:15 AssassinbeastAssassinbeast 1,2772 gold badges18 silver badges35 bronze badges 9
  • I am not 100% sure but I think you can just do [anyDomElement].GetElementsByTagName("div") – Marie Commented May 29, 2018 at 20:17
  • 2 Have you opened the jQuery core code and taken a look at the .filter() method? – Roko C. Buljan Commented May 29, 2018 at 20:18
  • Why not just write a wrapper that looks like the first code snippet but actually does the second? – Jonas Wilms Commented May 29, 2018 at 20:22
  • 1 there is no such thing as "native" JavaScript ...it is monly referred to as "vanilla" or ECMA6 script. – Martin Zeitler Commented May 29, 2018 at 20:38
  • 1 @MartinZeitler so you mean ECMAScript ;) – Roko C. Buljan Commented May 29, 2018 at 20:47
 |  Show 4 more ments

5 Answers 5

Reset to default 5

You can use the matches function to check if a CSS selector matches a given element.

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);
    }
}

This code can be written more succinctly (and with more modern code) using:

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

you can use 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>

you can change e.tagName to filter with something else :

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>

you can bine Array.filter() with 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 returns a NodeList not an array.

You'll need to convert it to an array

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

A very naive approach:

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)
  };
}

Usable as:

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

评论列表(0)

  1. 暂无评论