简体   繁体   English

通过 CSS3 选择器过滤 NodeList

[英]Filter NodeList by CSS3 selector

I have a NodeList object - let's say, returned by $element.children - and I would like to filter it by a CSS3 selector to only have certain elements left which meet my criteria.我有一个 NodeList 对象 - 比方说,由 $element.children 返回 - 我想通过 CSS3 选择器过滤它,只剩下某些符合我的条件的元素。 The function should basically look as following:该函数应基本上如下所示:

 var filter = (function($elementsToFilter, selector){ var $elementsFiltered; // ...? return $elementsFiltered; }); filter(document.querySelector('#element').children, '.two.three')
 <div id="element"> <div class="one two three">Yes</div> <div class="two three">Yes</div> <div class="two">No</div> <div class="three">No</div> </div>

  1. Might this not be useful for production (Bad practice)?这可能对生产没有用(不好的做法)?
  2. What is the fastest way to dynamically select the elements with 'Yes' in the 'filter' function?在“过滤器”功能中使用“是”动态选择元素的最快方法是什么?

Please note, that I am NOT looking for a framework solution, eg in jQuery.请注意,我不是在寻找框架解决方案,例如在 jQuery 中。 Thanks in advance!提前致谢!

Question 1:问题 1:

You most efficient method I can think of without using document.querySelector() is to use the contains() function on Element.classList .我能想到的不使用document.querySelector()最有效方法是在Element.classList上使用contains()函数。

for (elem in document.getElementById('element').children) {
  if (elem.classList.contains('two') && elem.classList.contains('three')) {
     // Do something
  }
}

Alternatively, you could merge your selectors into one like this:或者,您可以将选择器合并为一个,如下所示:

for (elem in document.querySelector('#element > .two.three')) {
  // Do something
}

Question 2:问题2:

If you control the server-side code which generates this HTML, you may find it easier to use a data attribute like this:如果您控制生成此 HTML 的服务器端代码,您可能会发现使用像这样的数据属性更容易:

<div id="element">
  <div class="one two three" data-select>Yes</div>
  <div class="two three" data-select>Yes</div>
  <div class="two">No</div>
  <div class="three">No</div>
</div>

Then with similar options to question 1:然后使用与问题 1 类似的选项:

for (elem in document.getElementById('element').children) {
  if (elem.dataset.select !== undefined) {
    // Do something
  }
}

The explicit check for undefined is necessary here ( ref ).此处需要显式检查undefined ( ref )。

for (elem in document.querySelector('#element > [data-select]') {
  // Do something
}

As an aside, javascript now has the Array.filter() function. Array.filter() ,javascript 现在有Array.filter()函数。 You can use this with Array.from() to replace your homebrew filter function (example taken from my first code snippet):您可以将它与Array.from()一起使用来替换您的自制filter功能(示例取自我的第一个代码片段):

let filtered = Array.from(document.getElementById('element').children).filter(elem => {
  return elem.classList.contains('two') && elem.classList.contains('three');
});

Or create a filterByClasses function:或者创建一个filterByClasses函数:

function filterByClasses(elements, classes) {
  return Array.from(elements).filter(elem => {
    return !classes.map(elem.classList.contains).includes(false);
  }
}

// Usage:
let filtered = filterByClasses(
                 document.getElementById('#element').children,
                 ['two', 'three']
               );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM