SCIFI User Interface Designer Lukasz Wieczorek
Posted on May 18, 2012 by lukasz on Uncategorized

how to add class to every 3rd element using jQuery

So last night I was working on my company website and was up against a weird problem that I needed to set a right margin, but also needed the last element to have no right margin so that it was flush against the edge. Design wise it looked terrible with the right margin.  The solution was to use CSS and jQuery as a team.

margin1

EDIT: looks like jQuery has a selector for this already, it’s called n-th child, DOH. Lesson learned. you can read on to see the logic if you would like though.

method looks like this:

 $(".listToTarget li:nth-child(x)").addClass("noRightMargin"); 

where x would be number you would like, so in this case it would be:

$(".listToTarget li:nth-child(3)").addClass("noRightMargin");

[divider] [/divider]

Well continue reading if you want to know the logic behind it using the modulus operator.

so lets start out with the html

<ul class="listToTarget">
	<li>One</li>
	<li>Two</li>
	<li>Three</li>
	<li>Four</li>
	<li>Five</li>
	<li>Six</li>
</ul>

Just your standard HTML list.

$(".listToTarget li").each( function (index) {
  index += 1;
  if(index % 3 == 0) {
    $(this).addClass("noRightMargin");
  }
 });

ok here is the good bit. What is happening here is using the .each, it is iterating through all the li items (one, two, three etc.) in this line:

$(".listToTarget li").each( function (index) { 

also notice we are passing index into the method. This allows us to use this in the method, otherwise jQuery has no idea how many objects there is. it’s similar to a for loop, except it already gives you an index:

var numberOfItems = Items.length //where items would be the number of li elements
for(var i = 0;  i < numberOfItems;  i++) {

The second line is to fix a weird thing that happens with jQuery, it makes sense in more cases but when you are trying to figure out the math for every third element it is a bit of a hinderance.

index += 1;

jQuery actually starts with the first element having an index of 0, so index of element “one” is really 0 and two is “1,” three is “2” and so on.

<ul class="listToTarget">
	<li>One</li>
	<li>Two</li>//this has index of 1</ul>
	<li>Three</li>//this has index of 2</ul>
	<li>Four</li>//this has index of 3</ul>
	<li>Five</li>//this has index of 4</ul>
	<li>Six</li>//this has index of 5</ul>
</ul>

not very conducive, so we fix it with:

index += 1;

ok, now the third line, what it does is use modulus. If you had high school math you can probably understand this one, its not too bad.

if(index % 3 == 0) {

what it is saying is; if the index of the element we are looping through (using .each) can be divisible by 3 and have no remainder than execute next line. If not, just ignore next three lines.

3 % 3 = 0(this would return true, and execute code)
4 % 3 = 1 (this would return false, and not continue)
5 % 3 = 2(this would return false, and not continue)
6 % 3 = 0 (this would return true, and execute code)

6 % 3 = 0 because three goes into 6 twice evenly with no remainder. easy peasey, right? lets continue…

the last bit of jQuery basically says, ok we passed the test, lets add a class to the third element:

 $(this).addClass("noRightMargin"); 

the  $(this) simply refers to  $(“.listToTarget li”), it’s basically a shortcut and temporarily stores element in variable so that we aren’t parsing the entire DOM all over again, which can be counter productive to load time. remember, this can only be used in side the each statement because of scope. To understand this better, check out my bud Brian on tutsplus, he has a great article explaining scope and goes into detail on closure (definitely something everyone should understand).

as for the .addClass all it does is say add a class to this element (remember we are now referring to listToTarget class which has li beneath it:$(“.listToTarget li”)) and the class to add is noRightMargin.

What is this magical noRightMargin?! well, it’s not actually magical, it’s just humble CSS:

noRightMargin {
 margin-right: 0px;
 }

this is relatively straight forward, all we did was set the margin to “0px.” Note: the specificity might be different for you, you might have to set a more precise specificity, read more about it here: CSS specificity

and that’s it! you’ve added a class to every third element. Bravo!

Leave a Reply