Search code examples
javascripthtmlcssmouseoverevent-listener

On mouseover Event Listener not changing color of grid item/div


Kind of a JavaScript noob here. I'm using DOM manipulation for a project and need to make it so that the grid items in my container change color after being hovered on. Why won't my hoverColor() function do anything? I assume that it is a problem with my "grid-item" class not working right.

I haven't adjusted the container sizing options yet, just trying to make the event listener work first.

//query selectors
const container = document.querySelector('#container');


//Function that creates GRID
function addDivs(rows, cols){
    container.style.setProperty('--grid-rows', rows);
    container.style.setProperty('--grid-cols', cols);
    for (i = 0; i < (rows * cols); i++){
      let square = document.createElement("div");
      square.classList.add('grid-item');
      container.appendChild(square);
    }
  hoverColor();
}

//function that creates a random color
let randomColor = function() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

//function that changes div color uponed being hovered
function hoverColor() {
  let item = document.querySelector('.grid-item');
  item.addEventListener('mouseover', () => {
    item.style.backgroundColor = `${randomColor()}`;
  });
}

//grid creationg
addDivs(16, 16);
:root {
  --grid-cols: 1;
  --grid-rows: 1;
}

#container {
  display: grid;
  grid-gap: 0.5em;
  grid-template-rows: repeat(var(--grid-rows), 1fr);
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  border: 3px solid black;
  padding: 1em;
}

#container:hover {
  box-shadow: 0 5px 5px rgba(0,0,0,0.19), 0 5px 5px rgba(0,0,0,0.23);
}

.grid-item {
  padding: 1em;
  border: 1px solid #ddd;
  text-align: center;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <div id="container"></div>
    <script src="script.js"></script>
  </body>
</html>


Solution

  • There were two problems with your code:

    1. Most fundamentally, you forgot to call your randomColor function. You were trying to stringify the function value itself as a CSS color value, which was never going to work. randomColor() is instead what you wanted, the color returned by the function.

    2. Your function would have only worked on the first grid item, because you were using querySelector, which only selects the first HTML element in the collection of matched elements. You instead want to use querySelectorAll, and iterate through the collection, adding the event listener to each.

    See working example below, with both fixes made:

    //query selectors
    const container = document.querySelector('#container');
    
    
    //Function that creates GRID
    function addDivs(rows, cols){
        container.style.setProperty('--grid-rows', rows);
        container.style.setProperty('--grid-cols', cols);
        for (i = 0; i < (rows * cols); i++){
          let square = document.createElement("div");
          square.classList.add('grid-item');
          container.appendChild(square);
        }
      hoverColor();
    }
    
    //function that creates a random color
    let randomColor = function() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
          color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
    
    //function that changes div color uponed being hovered
    function hoverColor() {
      let items = document.querySelectorAll('.grid-item');
      items.forEach(item => {
        item.addEventListener('mouseover', () => {
          item.style.backgroundColor = `${randomColor()}`;
        });
      });
    }
    
    //grid creationg
    addDivs(16, 16);
    :root {
      --grid-cols: 1;
      --grid-rows: 1;
    }
    
    #container {
      display: grid;
      grid-gap: 0.5em;
      grid-template-rows: repeat(var(--grid-rows), 1fr);
      grid-template-columns: repeat(var(--grid-cols), 1fr);
      border: 3px solid black;
      padding: 1em;
    }
    
    #container:hover {
      box-shadow: 0 5px 5px rgba(0,0,0,0.19), 0 5px 5px rgba(0,0,0,0.23);
    }
    
    .grid-item {
      padding: 1em;
      border: 1px solid #ddd;
      text-align: center;
    }
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>repl.it</title>
        <link href="style.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        <div id="container"></div>
        <script src="script.js"></script>
      </body>
    </html>