Mark Gregg
Mark Gregg

Reputation: 83

Why am I getting an uncaught type error with the following code?

The purpose of this code is to have 3 divs that change color when clicked and when the two colors in divs on the left make up the one on the right the user receives a positive message either on the console or the DOM. I thought I had this entirely figured out but now whenever I click a div I get an uncaught type error in Chrome that says:

Uncaught TypeError: Cannot read property 'backgroundColor' of undefined

Fiddle

var squares1 = document.getElementsByClassName('square1');
var squares2 = document.getElementsByClassName('square2');
var squares3 = document.getElementsByClassName('square3');

//change squares1 to either red,green, or blue
for(var i = 0; i < squares1.length; i++) {
    squares1[i].addEventListener("click", changeColor);
}
//change squares2 to either red, green, or blue
for(var i = 0; i < squares2.length; i++) {
    squares2[i].addEventListener("click", changeColor);
}
//changes squares3 to either red, green, blue, magenta, cyan, etc
for(var i = 0; i < squares3.length; i++) {
    squares3[i].addEventListener("click", changeColors);
}

function changeColor(event){
    if(event.target.style.backgroundColor == 'rgb(255, 0, 0)')
    {
        event.target.style.backgroundColor = 'rgb(0, 255, 0)';
        checkColors();
    }
    else if (event.target.style.backgroundColor == 'rgb(0, 255, 0)')
    {
        event.target.style.backgroundColor = 'rgb(0, 0, 255)';
        checkColors();

    }
    else
    {
        event.target.style.backgroundColor = 'rgb(255, 0, 0)';
        checkColors();

    }
}

function changeColors(event){
    if(event.target.style.backgroundColor == 'rgb(255, 0, 0)')
    {
        event.target.style.backgroundColor = 'rgb(255, 0, 255)';
        checkColors();
    }
    else if (event.target.style.backgroundColor == 'rgb(255, 0, 255)')
    {
        event.target.style.backgroundColor = 'rgb(255, 255, 0)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(255, 255, 0)')
    {
        event.target.style.backgroundColor = 'rgb(0, 0, 255)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(0, 0, 255)')
    {
        event.target.style.backgroundColor = 'rgb(0, 255, 255)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(0, 255, 255)')
    {
        event.target.style.backgroundColor = 'rgb(255, 0, 255)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(255, 0, 255)')
    {
        event.target.style.backgroundColor = 'rgb(0, 255, 0)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(0, 255, 0)')
    {
        event.target.style.backgroundColor = 'rgb(255, 255, 0)';
        checkColors();

    }
    else if (event.target.style.backgroundColor == 'rgb(255, 255, 0)')
    {
        event.target.style.backgroundColor = 'rgb(0, 255, 255)';
        checkColors();

    }

    else
    {
        event.target.style.backgroundColor = 'rgb(255, 0, 0)';
        checkColors();

    }
}

function checkColors(){
    if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 0, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(255, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(255, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(0, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(0, 255, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(0, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(0, 255, 255)';
        gotIt;
    }
else{youMissed;}

}

function gotIt(){
    console.log("You got it!")
}

function youMissed(){
    console.log("Try Again!")
}

Upvotes: 0

Views: 63

Answers (3)

saml
saml

Reputation: 794

Get elements by class name returns an array of elements. You need to specify which one. Try squares1[0] etc.

Upvotes: 1

Nikos M.
Nikos M.

Reputation: 8325

because this code:

function checkColors(){
    if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 0, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(255, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(255, 0, 0)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(255, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(0, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(0, 255, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 0, 255)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 0, 255)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(0, 255, 0)'){
        squares3.style.backgroundColor='rgb(0, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(255, 0, 0)'){
        squares3.style.backgroundColor='rgb(255, 255, 0)';
        gotIt;
    }
    else if (squares1.style.backgroundColor=='rgb(0, 255, 0)' && squares2.style.backgroundColor=='rgb(0, 0, 255)'){
        squares3.style.backgroundColor='rgb(0, 255, 255)';
        gotIt;
    }
else{youMissed;}

}

checks the squares1 etc.. as if it is a single element while actually it is a nodeList (so you need to check each squares1[i] and so on). probably same issue may be elsewhere in the code, did not check all.

Upvotes: 1

Stephan Muller
Stephan Muller

Reputation: 27600

You're using getElementsByClassName to fetch an array of elements that match your class name.

When binding your events, you correctly use the [0] index of that array to grab the first item in it:

squares1[i].addEventListener("click", changeColor);

However, in the checkColors() function you try to grab the backgroundColor of the entire array:

squares1.style.backgroundColor

An array doesn't have a background color, use squares1[0] like you did in the event listener to get the properties of the first element.

Upvotes: 1

Related Questions