0

I have a table with random words and I want specific words to be grayed out when clicking one of the buttons. On the second press of the same button, the words that weren’t grayed on the first click are now gray, and the rest go back to being white (the second press is like inverting the output in a way). Here’s my code:

    var pressCount = [0, 0, 0]; 
    var table = document.getElementsByTagName("td"); 
    
    document.body.addEventListener("click", function(event) {
        var target = event.target;
        var id = target.id;
        var index;
        
        if (id === "b1") {
            index = 0;
        } else if (id === "b2") {
            index = 1;
        } else if (id === "b3") {
            index = 2;
        } else if (id === "reset") {
            reset();
            return;
        } else {
            return;
        }
        
        pressCount[index]++;
        
        if (pressCount[index] === 1) { 
            target.style.backgroundColor = "green";
            var wordsToGray;
            
            if (index === 0) {
                wordsToGray = ["Behave", "Reach"];
            } else if (index === 1) {
                wordsToGray = ["Take", "Behave", "Utopia"];
            } else if (index === 2) {
                wordsToGray = ["Like", "Median"];
            }
            
            for (var i = 0; i < table.length; i++) { 
                if(wordsToGray.includes(table[i].innerHTML)) { 
                    table[i].style.color = "gray"; 
                } else {
                    table[i].style.color = "white";
                }
            } 
        } else if (pressCount[index] === 2) { 
            target.style.backgroundColor = "red";
            var wordsToGray;
            
            if (index === 0) {
                wordsToGray = ["Take", "Riddle", "Like", "Move", "Median", "Utopia", "Walk"];
            } else if (index === 1) {
                wordsToGray = ["Riddle", "Like", "Move", "Reach", "Median", "Walk"];
            } else if (index === 2) {
                wordsToGray = ["Take", "Behave", "Riddle", "Move", "Reach", "Utopia", "Walk"];
            }
            
            for (var i = 0; i < table.length; i++) { 
                if(wordsToGray.includes(table[i].innerHTML)) { 
                    table[i].style.color = "gray"; 
                } else {
                    table[i].style.color = "white";
                }
            } 
        } else { 
        target.style.backgroundColor = "";      
        pressCount[index] = 0;
        } 
    }); 
      function reset() { 
        var table = document.getElementsByTagName("td"); 
        for (var i = 0; i < table.length; i++) { 
            table[i].style.color = "white"; 
        } 
        var b1Button = document.getElementById("b1"); 
        b1Button.style.backgroundColor = ""; 
        var b2Button = document.getElementById("b2"); 
        b2Button.style.backgroundColor = "";
    var b3Button = document.getElementById("b3");
    b3Button.style.backgroundColor = "";
    pressCount = [0, 0, 0];
    }
table {
  font-size: 30px;
  width: 25%;
  text-align: center;
  border: none;
  background-color: black;
<table>
  <tr>
    <td style="color:white;">Take</td>
    <td style="color:white;">Behave</td>
    <td style="color:white;">Riddle</td>
  </tr>
  <tr>
    <td style="color:white;">Like</td>
    <td style="color:white;">Move</td>
    <td style="color:white;">Reach</td>
  </tr>
  <tr>
    <td style="color:white;">Median</td>
    <td style="color:white;">Utopia</td>
    <td style="color:white;">Walk</td>
  </tr>
</table>
<br>
<button id="b1">Button 1</button>
<button id="b2">Button 2</button>
<button id="b3">Button 3</button>
<button id="reset">RESET</button>

The problem is that when, for example, I press button 2 once and then button 1 once, the output shows only the words "Behave" and "Reach" grayed out (it’s the action on the first press of button 1). What I want the output to be, is the words "Take", "Behave", "Reach" and "Utopia" being grayed out. Meaning the action of button 2 isn’t overwritten.

I’m also thinking of having an action on the third button press that resets the buttons actions but I haven’t thought on how this is achievable and I’m getting ahead of myself here.

Vecipi
  • 1
  • 2
  • Do you want the buttons to ADD a selection to the previous selection? And when you press twice, invert ALL the words or only specific words? I think it would help you greatly to generalize your code a bit. Make the words an array `["utopia", "walk"]` and in the buttons only specify the positions that have to change `position 0 (first word) status 1 (grey)`. Then you could write a `for` loop that inverts or adds the status of each position. Something along those lines! – Kokodoko Feb 10 '23 at 14:07
  • Use [event delegation](//developer.mozilla.org/en/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation) instead of adding several event listeners — it’s more maintainable and applies to dynamically added elements. See [the tag info](/tags/event-delegation/info) and [this Q&A](/a/34896387/4642212). It’d probably be easier to have _one_ event listener for all buttons. Use the [`dataset` API](//developer.mozilla.org/en/docs/Web/API/HTMLElement/dataset) to store _just_ the affected words per button. Create a [state diagram](//en.wikipedia.org/wiki/State_diagram) to visualize your code. – Sebastian Simon Feb 10 '23 at 14:10
  • Inline event handlers like `onclick` are [bad practice](/q/11737873/4642212). They’re an [obsolete, cumbersome, and unintuitive](/a/43459991/4642212) way to listen for events. Always [use `addEventListener`](//developer.mozilla.org/en/docs/Learn/JavaScript/Building_blocks/Events#inline_event_handlers_%E2%80%94_dont_use_these) instead. – Sebastian Simon Feb 10 '23 at 14:10
  • @SebastianSimon I managed to rewrite the code using event delegation but I still can't figure out how to ADD a selection to the previous selection like the example I have mentioned above. – Vecipi Feb 10 '23 at 22:19

0 Answers0