4

I would like to add classes to an element in order from an array. I have three different classes, and I am not sure how to loop back to the beginning of the array to start over when I get to the end of the array of classes. Here is what I have so far:

var backgrounds = ["gray", "red", "blue"];
var elements = document.getElementsByClassName("blogpost");
var x = 0;
for (i = 0; i < elements.length; i++) {
    elements[i].classname += backgrounds[i];  //This is where I do not know how to add the elements in order
    x++; //This will get to the end of the array, how do I loop back to the beginning of the array after hitting the last element?
}
3
  • so you want the first one to be gray, second red, third blue, fourth great, fifth red, etc? Commented Jun 4, 2014 at 17:20
  • 2
    x = ++x % backgrounds.length will reset it, though you need backgrounds[x] instead of backgrounds[i] Commented Jun 4, 2014 at 17:22
  • or just i%backgrounds.length and disregard x all together. i is also incrementing Commented Jun 4, 2014 at 17:31

3 Answers 3

4

Just use modulo.

If you want classes like blogspot red then go with:

var backgrounds = ["gray", "red", "blue"];
var elements = document.getElementsByClassName("blogpost");
var len = backgrounds.length;
for (i = 0; i < elements.length; i++) {
    elements[i].className += ' ' + backgrounds[i%len];
}

It gets a little more interesting if you want classes like blogspotred, though.
getElementsByClassName doesn't return an array, but instead a node list, which will change once you start changing the classes (keep in mind, blogspotred doesn't fall under blogspot anymore). In that case you can, for example, do the following:

var backgrounds = ["gray", "red", "blue"];
var elements = Array.prototype.slice.call(document.getElementsByClassName("blogpost"));
var len = backgrounds.length;
for (i = 0; i < elements.length; i++) {
    elements[i].className += backgrounds[i%len];
}
Sign up to request clarification or add additional context in comments.

5 Comments

i really like the OP's question, and i would love to see how it's answered, but your solution doesn't seem to work for me: jsfiddle.net/nSXQ8 - is it because it needs to be called ondomready?
that's because in your jsfiddle, you don't actually set the background colour anywhere, you just call a string with that colour
that's not the way i'm checking it - i'm looking at dev tools and the class names are not added... i see why (someone else said somewhere here already): classname should read className... but when i do that, your solution concatenates with the existing one and skips every other element...
it should be elements[i].className += ' ' + backgrounds[i%len];, then it works, see jsfiddle.net/nSXQ8/2
Edited answer to address the above concerns.
1

You need to use mod. instead of using backgrounds[i], use backgrounds[i%3] where 3 is the length of the array

EDIT: in case you aren't aware of what that does, it gives the remainder. so first 0%3 is 0, then 1%3 is 1, 2%3 is 2, 3%3 is 0, 4%3 is 1, so on and so forth

Comments

0

What you're looking for is not a loop, but a modulus:

var backgrounds = ['gray', 'red', 'blue'];
var elements = document.getElementsByClassName('blogpost');
for (i=0; i<elements.length; i++) {
    // the following could be slightly optimized by storing the value to
    // backgrounds.length before the loop starts
    elements[i].className += ' ' + backgrounds[i%backgrounds.length];
}

Using i%3 gives you the remainder of your i iterator divided by 3. So, 0 -> 0, 1 -> 1, 2 -> 2, 3 -> 0, and so on.

Edit: Added correction from comments, and used superior choice to dynamically mod on the length of the array rather than static 3.

3 Comments

think you're making the same mistake as Nit: classname should read className ;)... but even then, same issue as with Nit's answer: class concatenated with existing one and only added to every other... see jsfiddle.net/nSXQ8/1
I have a feeling we both just copied directly from the OP, it's been a while since I've worked directly with class manipulation in native javascript, much preferring jQuery's methods for this myself.
well, for the sake of others seeing this and the correctness of an answer, you may want to edit it...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.