views:

284

answers:

2

hi there,

is there a way to replace following CSS with jQuery?

.quote-body .quote-body { background: #f5f5f5 }
.quote-body .quote-body .quote-body { background: #fff }
.quote-body .quote-body .quote-body .quote-body { background: #f5f5f5 }
.quote-body .quote-body .quote-body .quote-body .quote-body { background: #fff }
...
and so on
+5  A: 

Something like this might work:

$('.quote-body').each(function() {
    $(this).addClass($(this).parents('.quote-body').size() % 2 ? 'odd' : 'even');
});

For every .quotebody element, find the number of parent elements that has the class .quotebody and take modulo of two to define odd or even.

EDIT

Tested and working beautifully. This method might be a bit sluggish on complicated documents as for every element, jQuery has to traverse all the way back to the root element. But it works.

Working example: http://www.ulmanen.fi/stuff/oddevenchild.php

Tatu Ulmanen
that does it - big THANKS!
grzes
I tried something similar, setting odd and even classes, but making the class dependent of the parent's class. If the parent is odd, $(this) must be even. It depends a lot on the order in which $(".quote-body") finds/returns elements though
Sander Rijken
Remember to tick the answer as correct if you found this useful :)
Tatu Ulmanen
@grzes, don't forget to accept the correct answer ;-)
Sander Rijken
Sander, I thought of something like that too, but you'd had to first find the elements which have no parent .quote-bodies, and then select their immediate children etc.. And the child .quote-bodies might not be *immediate* children, so that would complicate things more.. :) This method might be slow, but at least it's short.
Tatu Ulmanen
A: 

I can't think of a simple selector that could solve this, but you may be able to achieve the intended results using a while loop:

var $quotes = $(<containing-elem>).children(".quote-body"), level = 0;

while($quotes.length > 0) {
    $quotes.css("background-color", (level % 2 ? "#f5f5f5" : "#fff"));
    level += 1;
    $quotes = $quotes.children(".quote-body");
}

To ensure that you don't initially select too many .quote-body elements, I'm first selecting the .quote-body elements that are immediate children of the containing element.

Xavi
This will only recurse into the first child of the first child, etc.
Sander Rijken
That is not true. The `children` function returns a all immediate children of the currently selected element, not just the first. The script I posted is tested and it does work. I'll upload an example page when I get home.
Xavi
OK, you're right, sorry about that. I was confused because .children doesn't *appear* to select the children of all matched elements (which it indeed does)
Sander Rijken
No worries. It's hard being a human compiler =P. In any case, here's the working example I promised: http://www.the-xavi.com/static/quotes.html
Xavi