0

I have a table like:

<table id="table">
    <tbody>
        <tr></tr>
        <tr>
            <td>
                <table>
                    <tbody>
                        <tr></tr>
                    </tbod>
                </table>
            </td>
        </tr>
     </tbody>
</table>

I'm using jQuery and there exists a stored selector to get the most outer table:

var x = $('#table')

Starting from that If want to get all first level <tr>-elements.

If I use one of those:

x.find('tbody > tr');
x.children('tbody').children();

… the first one will naturally select all nested <tr>-elements as well. The latter seems over-complicated and involves multiple queries.

Is there a way to make this faster/more efficient?

lampshade
  • 2,470
  • 3
  • 36
  • 74
  • Try with `jQuery filters..` – Deepak Ingole Sep 19 '13 at 10:40
  • FYI, "childen" are always elements of the "first level". You want to get the children only, not all *descendants* (see [this graphic](http://felix-kling.de/blog/2011/09/20/relationship-in-the-dom/)) Why do you think what you have is not efficient? How did you test the performance? – Felix Kling Sep 19 '13 at 10:57
  • I mean *children of course – Felix Kling Sep 19 '13 at 11:05
  • @FelixKling Thanks the word `descendant` didn't came to my mind, when writing this question - I edited the title by now. I knew that `children` wouldn't fit 100% as there's that `tbody` inbetween. And I didn't test it, no. I just thought that there must be some way to get this straight with only one query instead of two. – lampshade Sep 19 '13 at 12:24

3 Answers3

2

First thing, x.find('tbody > tr') would find all <tr>s. You would need to do x.find('> tbody > tr'), assuming x is x from your example.

I ran a test and this with both and this was my finding.

.children(): 3.013ms
>: 0.626ms

so the > method is faster than the .children() method. The function calls add up... barely.

Here's my JavaScript for the testing.

var $table = $('#table'), $usingChildren, $usingAngleBracket;

console.time('.children()');
$usingChildren = $table.children('tbody').children('tr');
console.timeEnd('.children()');

console.time('>');
$usingAngleBracket = $table.find('> tbody > tr');
console.timeEnd('>');

console.log( $usingChildren, $usingAngleBracket );
Bill Criswell
  • 32,161
  • 7
  • 75
  • 66
  • Cool, I didn't know I can use a selector starting with `>`, like `> tbody > tr`. That's pretty nice and looks even faster according to your measurement. Thanks for your effort. – lampshade Sep 19 '13 at 12:21
1

the fastest way to get direct children of a parent is .children, so what you can do is:

$('tbody').children('tr')

.find() will search child of child too, so you may not want to use that.

Bharat Soni
  • 2,824
  • 6
  • 23
  • 48
0

Use can use jQuery's .first() method to find the first <tr> element,

$('#mytable tr').first()

Although, as you wish to find the first <tr> that has nested child elements, you can filter it with .has(). For example: http://jsfiddle.net/cwL4q/3/

$("#mytable tr").has('tbody').first().css("background-color", "red" ); 

Although, I would strongly suggest simply labelling the 'nested' <tr>'s with a class, then you can simply access them much quicker as you know.

$('.nestedrow');

For the HTML below:

<table id="table">
        <tbody>
            <tr></tr>
            <tr class="nestedrow">
                <td>
                    <table>
                        <tbody>
                            <tr></tr>
                        </tbod>
                    </table>
                </td>
            </tr>
         </tbody>
    </table>
MackieeE
  • 11,751
  • 4
  • 39
  • 56