Question

I have an awkward problem, due to inheriting a shedload of really, really badly formatted HTML.

Basically I have some table rows like this:

<tr class="odd">...</tr>
<tr class="odd">...</tr>
<tr class="odd">...</tr>
<tr class="even">...</tr>
<tr class="even">...</tr>
<tr class="even">...</tr>
<tr class="odd">...</tr>
<tr class="odd">...</tr>
<tr class="odd">...</tr>

And what I need is a jQuery selector that will give me the first element of each block of classes. Is that clear enough? I'm not sure how else to explain it.

So in the example case I would want rows 1, 4, and 7.

Ive done this so far by selecting every nth child, but Ive now realised this wont work as there wont always be the same number of rows in each block of classes.

Any help you guys can give it appreciated, as always :)

Cheers!

Était-ce utile?

La solution

You'll need to employ some strategic use of :not() and adjacent sibling selectors:

$('tr.odd:first-child, tr.even:first-child, tr:not(.odd) + tr.odd, tr:not(.even) + tr.even')

The tr:not(...) + tr... bits select any tr element that's directly preceded by a tr that does not have the same class name. You can't do this dynamically (e.g. with some sort of wildcard), but it's entirely possible if you specify each class name separately. This will ensure you only select the first element in each contiguous group.

The reason the :first-child pseudo is required is simply because + won't match the first child, since it implies a relationship between an element and its preceding sibling. Note that :first-child accounts for the very first tr only. You could replace tr.odd:first-child, tr.even:first-child with simply tr:first-child if every tr element will have exactly one of either class name, but I specify them anyway for clarity's sake.

Last but not least, this doubles as a valid CSS selector, so you can use it in a stylesheet as well if you like.

Autres conseils

$('tr.odd:not(.odd+.odd),tr.even:not(.even+.even)')

This just takes any .odd element which isn't following another .odd, and any .even element which isn't following another .even element.

this may help you

$('button').click(function() {
    var lastGroup = ''
    $('.groups tr').each(function() {
        if(lastGroup != this.className) {
            $(this).css('background-color', 'red');
            lastGroup = this.className;
        }
    });
});

explanation: loop through all the TR and verify if the class name (this.className) is equal to lastGroup. if not equal, we have a new group (first element of the group). if equal, ignore and continue. this will work with any class name used.

JSFiddle: http://jsfiddle.net/bq7zB/

Loop through and check if the current element matches the last one, otherwise it's the first of its set:

var lastClass = false;
$('tr.odd, tr.even').each({ function() {
    lastClass = $(this).attr('class');
    if($(this).attr('class') != lastClass){
        // Do your conditional stuff here
    }
}
  var prevClass = '';
  $('tr').each(function(){
    var thisClass = $(this).attr('class');
    if (prevClass === thisClass) {
     //do nothing?   
    } else {
    //push in array? do something to the row?   
    }
 });
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top