My to-read shelf on GoodReads is a mix of published and unpublished books making it hard to find something published to read. I figured I could throw together a GreaseMonkey script that would change the background of the entry for the books that haven't yet been published.

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

Does console.log(book); in your loop show what you expect it to show? Or book.tagName?
–
David ThomasSep 22 '12 at 14:21

Personaly I do not think you can provide 2 class name in the same command. Then your For loop, there is a proplem there for sure, you requesting to go inside 2 class name choosing other class name and taking the textcontent. And do not forget when you use getElementsByClassName it will return array so you need to choose which one you want.
–
Manuel ChoucinoSep 22 '12 at 14:22

5 Answers
5

You cannot chain getElementsByClassName like that. That function operates on a DOM element, but returns an object.

for (var book in books) will loop on object properties that are not accounted for, and will crash this code. books is an object, not an array.

book.style.backgroundColor is not a function and that is not how to set a style.

Nowadays, getElementsByClassName is seldom the best approach for this kind of thing; use querySelectorAll for more: flexibility/power/precision.

Fixing all the problems, here's code that should work -- assuming that the page structure really matches the code structure from the question. Post a relevant HTML snippet and/or link to the exact page, if it does not.

This works mostly. The one problem is that the style is being applied to the div containing the date. I was looking to apply the style to the tr with the class .bookalike review that contain the dive with the date.
–
Mr AlphaSep 22 '12 at 21:15

getElementsByClassName returns an array-like object of the appropriate elements (there can be more than one with a given class). You will have to loop over each one and execute getElementsByClassName on each. Nested getElementsByClassNames are not merged by default.

There is a further problem (aside from trying to call getElementsByClassName on a NodeList) that for (var book in books) won't do what you want. in doesn't do a foreach as you would expect; it gets every property from the target object. Because of the way Javascript objects work, for an array, this would be the array indexes; for a NodeList, it is the properties of the NodeList (which will be the array indexes, plus the string "length" and the string "item"), which will not be useful for your loop.

You can only use getElementsByClassName on a single Element object, not a NodeList or HTMLCollection like what's returned by getElementsByClassName. That is, the problem probably lies in your chaining call where you call that function again on itself.