Search code examples
javascriptjsonbackground-color

Why are my divs not updating their background color?


For a project in class we have to make an application that displays to a user color harmonies which are stored in a JSON file. (Like direct harmony = color on the opposite side of the color wheel of another color.) I made an application that requires a user to select a color, and then select the color harmony they would like displayed for that color. The application works except for one thing: sometimes the divs don't update when switching colors.

An example: User selects Red then Direct. The Application should show 2 boxes, one being red and the other being the direct harmony of red which is green. Then the user selects Yellow and Direct. The boxes should change to Yellow and Blue respectively. Now the issue occurs if the user were to then select Red and Direct again. Only the top box changes color, the bottom box stays blue. And none of the innerHTML, which I have just to show what color is in the box, updates either.

I can't follow the logic train that the code is using and as far as I'm aware, everything should be changing as it's supposed to. What is going wrong?

Javascript:

var primary = document.querySelector('#primary');
var harmony1 = document.querySelector('#harmony1');
var harmony2 = document.querySelector('#harmony2');
var direct = document.querySelector('#direct');
var split = document.querySelector('#split');
var analogous = document.querySelector('#analogous');
var bgColor = "";



fetch("data/data.json")
    .then( (response) => { return response.json() })
    .then((jsonData) => {
        data = jsonData;
    })


function redColor() {

    bgColor = data.colors[0].hex;

    direct.addEventListener("click", redDirectHarmony);
    split.addEventListener("click", redSplitHarmony);
    analogous.addEventListener("click", redAnalogousHarmony);


}

function redDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Red";

    harmony1.style.backgroundColor = data.colors[0].direct[1];
    harmony1.innerHTML = "#00ff00";

    harmony2.style.backgroundColor = "white";
    harmony2.innerHTML = "";

}

function redSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Red";

    harmony1.style.backgroundColor = data.colors[0].split[1];
    harmony1.innerHTML = "#0080ff";

    harmony2.style.backgroundColor = data.colors[0].split[2];
    harmony2.innerHTML = "#00ff80"
}

function redAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Red";

    harmony1.style.backgroundColor = data.colors[0].analogous[1];
    harmony1.innerHTML = "#ff8000";

    harmony2.style.backgroundColor = data.colors[0].analogous[2];
    harmony2.innerHTML = "#ff0080";
}

function yellowColor() {

    bgColor = data.colors[1].hex;

    direct.addEventListener("click", yellowDirectHarmony);
    split.addEventListener("click", yellowSplitHarmony);
    analogous.addEventListener("click", yellowAnalogousHarmony);

}

function yellowDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Yellow";

    harmony1.style.backgroundColor = data.colors[1].direct[1];
    harmony1.innerHTML = "#0000ff";

    harmony2.style.backgroundColor = "white";
}

function yellowSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Yellow";

    harmony1.style.backgroundColor = data.colors[1].split[1];
    harmony1.innerHTML = "#8000ff";

    harmony2.style.backgroundColor = data.colors[1].split[2];
    harmony2.innerHTML = "#0080ff"
}

function yellowAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Yellow";

    harmony1.style.backgroundColor = data.colors[1].analogous[1];
    harmony1.innerHTML = "#80ff00";

    harmony2.style.backgroundColor = data.colors[1].analogous[2];
    harmony2.innerHTML = "#ff8000";
}

function greenColor() {

    bgColor = data.colors[2].hex;

    direct.addEventListener("click", greenDirectHarmony);
    split.addEventListener("click", greenSplitHarmony);
    analogous.addEventListener("click", greenAnalogousHarmony);

}

function greenDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Green";

    harmony1.style.backgroundColor = data.colors[2].direct[1];
    harmony1.innerHTML = "#800080";

    harmony2.style.backgroundColor = "white";
}

function greenSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Green";

    harmony1.style.backgroundColor = data.colors[2].split[1];
    harmony1.innerHTML = "#800040";

    harmony2.style.backgroundColor = data.colors[2].split[2];
    harmony2.innerHTML = "#400080";
}

function greenAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Green";

    harmony1.style.backgroundColor = data.colors[2].analogous[1];
    harmony1.innerHTML = "#008040";

    harmony2.style.backgroundColor = data.colors[2].analogous[2];
    harmony2.innerHTML = "#408000";
}

function blueColor() {

    bgColor = data.colors[3].hex;

    direct.addEventListener("click", blueDirectHarmony);
    split.addEventListener("click", blueSplitHarmony);
    analogous.addEventListener("click", blueAnalogousHarmony);

}

function blueDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Blue";

    harmony1.style.backgroundColor = data.colors[3].direct[1];
    harmony1.innerHTML = "#ffff00";

    harmony2.style.backgroundColor = "white";
}

function blueSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Blue";

    harmony1.style.backgroundColor = data.colors[3].split[1];
    harmony1.innerHTML = "#80ff00";

    harmony2.style.backgroundColor = data.colors[3].split[2];
    harmony2.innerHTML = "#ff8000";
}

function blueAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Blue";

    harmony1.style.backgroundColor = data.colors[3].analogous[1];
    harmony1.innerHTML = "#8000ff";

    harmony2.style.backgroundColor = data.colors[3].analogous[2];
    harmony2.innerHTML = "#0080ff";
}

function orangeColor() {

    bgColor = data.colors[4].hex;

    direct.addEventListener("click", orangeDirectHarmony);
    split.addEventListener("click", orangeSplitHarmony);
    analogous.addEventListener("click", orangeAnalogousHarmony);

}

function orangeDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Orange";

    harmony1.style.backgroundColor = data.colors[4].direct[1];
    harmony1.innerHTML = "#0059ff";

    harmony2.style.backgroundColor = "white";
}

function orangeSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Orange";

    harmony1.style.backgroundColor = data.colors[4].split[1];
    harmony1.innerHTML = "#2600ff";

    harmony2.style.backgroundColor = data.colors[4].split[2];
    harmony2.innerHTML = "#00d9ff";
}

function orangeAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Orange";

    harmony1.style.backgroundColor = data.colors[4].analogous[1];
    harmony1.innerHTML = "#d9ff00";

    harmony2.style.backgroundColor = data.colors[4].analogous[2];
    harmony2.innerHTML = "#ff2600";
}

function violetColor() {

    bgColor = data.colors[5].hex;

    direct.addEventListener("click", violetDirectHarmony);
    split.addEventListener("click", violetSplitHarmony);
    analogous.addEventListener("click", violetAnalogousHarmony);

}

function violetDirectHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Violet";

    harmony1.style.backgroundColor = data.colors[4].direct[1];
    harmony1.innerHTML = "#82ee82";

    harmony2.style.backgroundColor = "white";
}

function violetSplitHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Violet";

    harmony1.style.backgroundColor = data.colors[4].split[1];
    harmony1.innerHTML = "#82eeb8";

    harmony2.style.backgroundColor = data.colors[4].split[2];
    harmony2.innerHTML = "#b8ee82";
}

function violetAnalogousHarmony() {

    primary.style.backgroundColor = bgColor;
    primary.innerHTML = "Violet";

    harmony1.style.backgroundColor = data.colors[4].analogous[1];
    harmony1.innerHTML = "#ee82b8";

    harmony2.style.backgroundColor = data.colors[4].analogous[2];
    harmony2.innerHTML = "#b882ee";
}

And I don't know if the issue could be coming from the actual JSON file, but just in case this is said JSON:

{
  "colors": [
    {
      "color": "red",
      "hex": "#FF0000",
      "direct": ["#FF0000","#00ff00"],
      "analogous": ["#FF0000","#ff8000", "#ff0080"],
      "split": ["#FF0000","#0080ff", "#00ff80"]
    },
    {
      "color": "yellow",
      "hex": "#FFFF00",
      "direct": ["#FFFF00","#0000ff"],
      "analogous": ["#FFFF00","#80ff00", "#ff8000"],
      "split": ["#FFFF00","#8000ff", "#0080ff"]
    },
    {
      "color": "green",
      "hex": "#008000",
      "direct": ["#008000","#800080"],
      "analogous": ["#008000","#008040", "#408000"],
      "split": ["#008000","#800040", "#400080"]
    },
    {
      "color": "blue",
      "hex": "#0000FF",
      "direct": ["#0000FF","#ffff00"],
      "analogous": ["#0000FF","#8000ff", "#0080ff"],
      "split": ["#0000FF","#80ff00", "#ff8000"]
    },
    {
      "color": "orange",
      "hex": "#FFA500",
      "direct":["#FFA500","#0059ff"],
      "analogous": ["#FFA500","#d9ff00", "#ff2600"],
      "split": ["#FFA500","#2600ff", "#00d9ff"]
    },
    {
      "color": "violet",
      "hex": "#EE82EE",
      "direct": ["#EE82EE","#82ee82"],
      "analogous": ["#EE82EE","#ee82b8", "#b882ee"],
      "split": ["#EE82EE","#82eeb8", "#b8ee82"]
    }
  ]
}

Solution

  • You problem is in the way you are using event listeners. Each time you click a color, you add a new listener. Then when you click direct, it processes all the listeners in order. So you set red, add red direct listener, then set yellow, add yellow direct listener, then red again, but there's already a red listener and it won't add again. If you step through the code or add alerts or alter the behavior in some manner that lets you log which methods are called, you'll see that if you click red, then yellow, it is actually calling both methods -- redDirectHarmony first, then yellowDirectHarmony -- once you click direct.

    If your red/yellow/red scenario, it doesn't call redDirectHarmony again after that because it didn't add the event listener twice.

    You should refactor so that you only have one method per button function.

    Simplified Example:

    var primary = document.querySelector('#primary');
    var harmony1 = document.querySelector('#harmony1');
    var harmony2 = document.querySelector('#harmony2');
    var direct = document.querySelector("#direct");
    var myColor = { };
    var data = {
      "colors": [
    {
      "color": "red",
      "hex": "#FF0000",
      "direct": ["#FF0000","#00ff00"],
      "analogous": ["#FF0000","#ff8000", "#ff0080"],
      "split": ["#FF0000","#0080ff", "#00ff80"]
    },
    {
      "color": "yellow",
      "hex": "#FFFF00",
      "direct": ["#FFFF00","#0000ff"],
      "analogous": ["#FFFF00","#80ff00", "#ff8000"],
      "split": ["#FFFF00","#8000ff", "#0080ff"]
    },
    {
      "color": "green",
      "hex": "#008000",
      "direct": ["#008000","#800080"],
      "analogous": ["#008000","#008040", "#408000"],
      "split": ["#008000","#800040", "#400080"]
    },
    {
      "color": "blue",
      "hex": "#0000FF",
      "direct": ["#0000FF","#ffff00"],
      "analogous": ["#0000FF","#8000ff", "#0080ff"],
      "split": ["#0000FF","#80ff00", "#ff8000"]
    },
    {
      "color": "orange",
      "hex": "#FFA500",
      "direct":["#FFA500","#0059ff"],
      "analogous": ["#FFA500","#d9ff00", "#ff2600"],
      "split": ["#FFA500","#2600ff", "#00d9ff"]
    },
    {
      "color": "violet",
      "hex": "#EE82EE",
      "direct": ["#EE82EE","#82ee82"],
      "analogous": ["#EE82EE","#ee82b8", "#b882ee"],
      "split": ["#EE82EE","#82eeb8", "#b8ee82"]
    }
    ]
    };
    
    function setColor(colorName) {
       for (var i = 0; i < data.colors.length; i++)
       {
           if (data.colors[i].color == colorName)
           {
              myColor = data.colors[i];
              primary.style.backgroundColor = myColor.hex;
              primary.innerHTML = myColor.color;
    
           }
       }
    }
    
    function directHarmony() {
        harmony1.style.backgroundColor = myColor.direct[1];
        harmony1.innerHTML = myColor.direct[1];
    }
    <button onclick="setColor('red')">red</button>
    <button onclick="setColor('yellow')">yellow</button>
    <button id="direct" onclick="directHarmony()">Direct</button>
    <div id="primary">
    primary
    </div>
    <div id="harmony1">
    harmony1
    </div>
    <div id="harmony2">
    harmony2
    </div>