jQuery: select tr's where td's meeting mul

2019-07-11 14:24发布

问题:

I was wondering, whether it's possible to select <tr>'s from a <table> where <td>'s meets multiple conditions. For example (see sample table at the end ):

Get all <tr>'s where first column is "Audi" AND second column is "red"

I've allready find out how to filter by one collumn:

$('tr:has(td:nth-child(1):contains("Audi"))').doSomeThing();

But my problem is how to filter with an AND condition like:

$('tr:has(td:nth-child(1):contains("Audi") && td:nth-child(2):contains("red"))').doSomeThing();

I know that there is the Multiple Attribute Selector, but since i'm searching for the .text() property it's not apropriate for my problem.

My sample table:

<table id="list">
<tr>
    <td>Audi</td>
    <td>red</td>
</tr>
<tr>
    <td>Audi</td>
    <td>yellow</td>
</tr>
<tr>
    <td>Audi</td>
    <td>green</td>
</tr>
<tr>
    <td>BMW</td>
    <td>red</td>
</tr>
<tr>
    <td>BMW</td>
    <td>yellow</td>
</tr>
<tr>
    <td>BMW</td>
    <td>green</td>
</tr>
    ...
</table>

Thanx for your help!

回答1:

Use the filter method to narrow down your initial selection based on other conditions.

$('tr:has(td:nth-child(1):contains("Audi"))').filter(':has(td:nth-child(2):contains("red"))').doSomeThing();

If you're looking for a single selector, here is the less readable:

$('tr:has(td:nth-child(1):contains("Audi")):has(td:nth-child(2):contains("red"))').doSomeThing();

Here is a demonstration: http://jsfiddle.net/8Mnsf/2/

You could also improve readability somewhat by going for:

$('tr')
    .has('td:nth-child(1):contains("Audi")')
    .has('td:nth-child(2):contains("red")')
    .doSomeThing();


回答2:

Your best choice would be to use the filter() method. Relying on jQuery's custom selectors (:contains, :has, etc.) is not the best idea in most cases, because the native querySelectorAll() cannot be used when available, which can become a performance problem.

From the manual:

Because :has() is a jQuery extension and not part of the CSS specification, queries using :has() cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use $("your-pure-css-selector").has(selector/DOMElement) instead.

Also a selector like that is hardly readable, so it reduces maintainability as well. A filter() method is simple readable code that can be reasonably commented as well if needed.

Something like this:

$('tr').filter(function () {
    var $cells = $(this).children('td');
    return $cells.first().text() === 'Audi'
         && $cells.eq(1).text() === 'red';
});

jsFiddle Demo