Change of class on an event listener is only temporary, classList.replace is only for one click, how to make it permanent

Viewed 163

[![enter image description here][1]][1]I wanted to create a simple app for drawing by coloring the background of squares by clicking on them. I added a click event on every li which changes the background-color by adding a class. However, I'd like to take it to the next level by adding 4 buttons that would change the colors of the hightlight. Can anyone help me with that?

So my problem is: How to click a button (li in the header) that will select the color for my original event listener on ul class=grid li?

 <header>
      <ul class="header">
        <li class="black">Black</li>
        <li class="red">Red</li>
        <li class="blue">Blue</li>
        <li class="orange">Orange</li>
      </ul>
    </header>
    <ul class="grid">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      .......
     
const myElements = document.getElementsByTagName("li");
for (let i = 0; i < myElements.length; i++) {
  myElements[i].addEventListener("click", function () {
    let selected = myElements[i];
    selected.classList.toggle("highlight");
  });
}

I tried (remove and add new class, replace class, toggle)

black.addEventListener("click", function () {
  selected.classList.replace("highlight", "black");
});

But the change of background color is only one-off. I want to new class become permanent. 1]: https://i.stack.imgur.com/Fgg87.png

2 Answers

By adding event listeners to both your ul.header li and ul.grid li you will achieve this. ul.header li click event listener will save the color you want and the ul.grid li click will use that saved color to apply it.

var selcolor = '';

const colorbtns = document.querySelectorAll('ul.header > li');
const griditems = document.querySelectorAll('ul.grid > li');

colorbtns.forEach(function(el) {
    el.addEventListener("click", function(e) {
    selcolor = e.target.className;
    console.log(selcolor);
  });
});

griditems.forEach(function(el) {
    el.addEventListener("click", function(e) {
       if(el.classList.length <= 0) {
           el.classList.add(selcolor);
       }
       else {
           el.className = "";
       }
   });
});
.header li {
  display:inline-block;
  color:#fff;
  padding:5px;
}

.grid li {
  width:50px;
  height:50px;
  display:inline-block;
  border:1px solid black;
}

.black { background-color:black; }
.red { background-color:red; }
.blue { background-color:blue; }
.orange { background-color:orange; }
<header>
  <ul class="header">
    <li class="black">Black</li>
    <li class="red">Red</li>
    <li class="blue">Blue</li>
    <li class="orange">Orange</li>
  </ul>
</header>
<ul class="grid">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

EDIT

Updated the code

el.addEventListener("click", function(e) {
    el.classList.add(selcolor);
});

To

el.addEventListener("click", function(e) {
    if(el.classList.length <= 0) {
        el.classList.add(selcolor);
    }
    // this else statement will clear the color on second click if theres already one color assigned
    else {
       el.className = "";
    }
  });

That way you can only assign the color once as per your comment

But the change of background color is only one-off

Related