How to modify style to HTML elements (styled externally with CSS) using JS?

so when i click on the <p> tag of the home class, i want it to change color to green but it doesn't work and idk why. the click registers fine (as the console.log("test") displays just fine) but the rest of the function to change the color won't work. here's my css, html and js code (the js code is contained in the HTML, so it's not an external file or anything):

.greyRect {

  height:150px;
  width:1350px;

  background-color: #D3D3D3;


}
h1 {
  text-align: center;
}
h2 {
    text-align: center;
}
.home {



box-sizing: border-box;
width:80px;
height:35px;

line-height: 2;
  position: relative;
left:350;
  color:white;

}
.casinocraps {
  background-color: grey;

box-sizing: border-box;
width:120px;
height:35px;
text-align: center;
line-height: 2;
  position: relative;
left:460;
bottom:50;
  color:white;
}
.tictactoe {
  background-color: grey;
  box-sizing: border-box;
  width:90px;
  height:35px;
  text-align: center;
line-height: 2;
    position: relative;
left:600;
bottom:100;
    color:white;
}
.bingo {
  background-color: grey;
  box-sizing: border-box;
  width:80px;
  height:35px;
  text-align: center;
  line-height: 2;
    position: relative;
  left:700;
  bottom:150;
    color:white;
}
.concentration {
  background-color: grey;
  box-sizing: border-box;
  width:100px;
  height:35px;
  text-align: center;
  line-height: 2;
    position: relative;
  left:800;
  bottom:200;
    color:white;
}
footer {
  text-align: center;
    line-height: 4;
      position: relative;
  top:125;
  right:15;
  height:70px;
  width:1365px;

  background-color: #D3D3D3;
}
.border {
  height: 50px;
  width: 100px;
  border: 4px solid green;
  background-color: #555;
  position: relative;
  top:20;
  left:100;
}
.rectangle {
  height: 50px;
  width: 100px;
  background-color: #555;
  position: relative;
  top:50;
  left:100;
}
<html>
  <head>

    <meta charset="utf-8">

    <title></title>
      <link rel="stylesheet" type="text/css" href="cssForAss4.css">
  </head>
  <body>

<header class="greyRect" >
<h1>Assignment 1</h1>

<h2>Home Page</h2>
<nav>
<p class="home" onclick="selectHome()">
Home
</p>
<p class="casinocraps">

<b>Casino Craps</b>
</p>
<p class="tictactoe">

<b>Tic-Tac-Toe</b>
</p>
<p class="bingo">

<b>Bingo</b>
</p>
<p class="concentration">

<b>Concentration</b>
</p>
</nav>
<div class="border">
</div>
<footer >Footer</footer>

</header>

<script>
function selectHome() {
  console.log("test");

document.getElementsByClassName("home").style += "background-color:green;";


}
</script>
  </body>
</html>

Solution 1:

Others have suggested .getElementsByClassName("home")[0], which is a terrible idea.

First, .getElementsByClassName() returns a node list of all the matching elements. If you are only interested in the first one, it makes no sense to find that one and then keep scanning for more matches and then discard all but the first one found, which is what this code does.

Second, .getElementsByClassName() returns a "live" node list. This means that every time you interact with the list, the entire DOM is searched again for matches, ensuring that you have the most up to date set in your list. This can be useful in applications where nodes are being added and removed dynamically, but those use cases aren't as common.

FYI: .getElementsByTagName(), .getElementsByName(), and node.childNodes also return live node lists.

All of these previously mentioned methods date back to the earliest days of the DOM API, when it was still the "wild west" days of web development. They are all over two decades old and have much better alternatives today (i.e. .querySelector(), .querySelectorAll(), .closest()).

When it's not necessary to keep an up to date list, .querySelectorAll() is the way to go. And frankly, even if you do need an updated node list, you're still better off with .querySelectorAll() and just run it again manually at the point where you need an updated list.

Here's a good page that discusses this and here's what it has to say:

How to Think About Live Object?

Live object is not intuitive. You can think of it as delayed evaluation or lazy evaluation. Method or property of live object is re-computed when their result is accessed.


But, in this case, we don't even want a node list, we just want a single node. The correct solution would be:

document.querySelector(".home");

.querySelector() scans the document for the first element that matches the supplied selector and, if found, returns a reference to that single node. Otherwise, it returns undefined.

Solution 2:

.style is actually a js object with keys corresponding to css properties.

As Adarsh said

document.getElementsByClassName("home")[0].style.backgroundColor = "green"

Edit - Don't do this. As Scott Marcus explains, this is pretty bad. Definitely should use querySelector('.home') to get the element.

Generally, if a property has a hyphen like background-color, you convert it to camel case ie backroundColor

Check out MDN - HTMLElement.style

Solution 3:

Do it like this:

function selectHome() {
  document.getElementsByClassName("home")[0].style.backgroundColor = "green";
}
<p class="home" onclick="selectHome()">
  Home
</p>