-3

I'm trying to test some JS on a page i'm making. I'm new to it so i'm trying something simple. Apparently it's too challenging for me. Here is my code for the div:

<div class="ni">
    <div class="ni_image" onclick="changeColor()">
        <div class="text_box">
            <h3>Northern Ireland</h3>
        </div>
    </div>
    <div class="ni_info">
        <p>info</p>
    </div>
</div>

Here is the CSS for the outer div if you need it:

.ni {
    width: 600px;
    height: 220px;
    display: block;
    margin: 0px 0px 60px 0px;
}

And the style I'm trying to change in .ni_image:

background-color: lightblue;

The only other style attributes for this div are width/height, display, and margins/padding. If they're helpful please comment and I'll add them.

Finally here is the JS I'm testing:

function changeColor() {
document.getElementsByClassName('.ni_image').style.backgroundColor = "red";
}

I've looked at StackOverflow and loads of other forums, and from what I've read I have no idea where I'm going wrong. I've linked the local .js file with a script tag in the head tag.

Any help would be greatly appreciated.

  • You don't need to include the `.` in your `getElementsByClassName('.ni_image')`. Try `getElementsByClassName('ni_image')` – Tyler Roper Aug 31 '16 at 15:31

6 Answers6

1

When providing arguments to getElementsByClassName you don't have to include dot

document.getElementsByClassName('ni_image')

And remember it returns an HTMLCollection.

mic4ael
  • 7,974
  • 3
  • 29
  • 42
  • Thanks for the help. – Alex Underhill Aug 31 '16 at 15:38
  • 1
    `getElementsByClassName` does not return an array, it returns an `HTMLCollection`. If it returned an array, you could immediately use Array methods on it such as `map`. However, it must be converted to an array before that can happen. [Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) – KevBot Aug 31 '16 at 15:40
1

document.getElementsByClassName('ni_image') returns an Arraylike HTMLCollection, so you must use it as an array https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

document.getElementsByClassName('ni_image')[0].style.backgroundColor = "red";

Also as already stated, you can not use css selectors with this function, so no dot needed.

You can check the documentation of this function http://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp and it says that the return value is of type NodeList, so technically it is not an Array but for the most use cases it can be handled as one.

A quick tip I can give: if the function is something like "getElementXXX" like in getElementById it will return a single Object and when it says "getElementsXXX" like in getElementsByClassName or getElementsByName it will return a NodeList

Dimitri L.
  • 4,499
  • 1
  • 15
  • 19
  • Thanks for the help. It works now. One thing though - what makes it an array? I thought that an array was a var with multiple values? Or is it because there is another div inside it? – Alex Underhill Aug 31 '16 at 15:37
  • `getElementsByClassName` does not return an array, it returns an `HTMLCollection`. If it returned an array, you could immediately use Array methods on it such as `map`. However, it must be converted to an array before that can happen. [Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) – KevBot Aug 31 '16 at 15:40
  • @KevBot thanks for your tip. Normally it is enough to know that it returns an array. As for the question why it returns multiple Nodes instead of one: it is because there can be multiple Elements with the same css class and this function returns all of them. – Dimitri L. Aug 31 '16 at 15:49
  • 1
    It is not enough to think that it returns an Array, because, it does not. It is "Array-Like", in the sense that it has indexes, etc. What happens when people start thinking they can do this: `document.getElementsByClassName('foo').forEach(...)`. You get an error that "`forEach is not a function`". That is because it is not an array. – KevBot Aug 31 '16 at 15:56
1

Assuming that you have multiple divs that have the ni_image class you would need to loop through the HTMLCollection that is returned by getElementsByClassName() if you notice it says Elements in the function - as in plural. That is because a class name can be applied to any number of elements, so it is always returning an HTMLCollection with all of those elements.

var elements = document.getElementsByClassName('ni_image');

for(var i = 0; i < elements.length; i++){
    elements[i].style.backgroundColor = "red";
}

You can access the elements of the HTMLCollection by either using the [index] notation or .items(index)

Adjit
  • 10,134
  • 12
  • 53
  • 98
0

document.getElementsByClassName returns a list. Setting the style field of a list will do nothing.

You need to loop over the list it returns:

var elements = document.getElementsByClassName('ni_image');
elements.forEach(function(e) {
     e.style.backgroundColor = "red";
});
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
0

document.getElementsByClassName() returns an array-like object of all child elements which have all of the given class names.(MDN)

Try:
document.getElementsByClassName('ni_image')[0].style.backgroundColor = 'red';

klioen
  • 47
  • 3
-2

Don't prepend your class name with ".":

document.getElementsByClassName('ni_image').style.backgroundColor = "red";