Search code examples
javascriptarraysif-statementinnerhtmlonkeyup

How do I get event.key to display each letter in my html?


Thank you for taking the time to help!

I am working on a hangman game and am running into a small issue. I am able to see the userInput if it is any other letter than what's below in my if else statements. The problem is that I want it to display that event, and then display any other event that wasn't already keyed to displayed alongside. For example: if userInput is === "k" then userInput is === "b", I would like it to keep the display of "k" in my html and then alongside it "b".

Also if there is a better way to write my if else statement with a loop or using forEach that would be helpful. I am new to the concepts. Thanks again.

   document.onkeyup = function(event) {
            var userInput = event.key;

if (currentWord === "taco"){ if (userInput === "t" ) { document.getElementById("1st-letter").innerHTML = userInput; } else if (userInput === "a") { document.getElementById("2nd-letter").innerHTML = userInput; } else if (userInput === "c") { document.getElementById("3rd-letter").innerHTML = userInput; } else if (userInput === "o") { document.getElementById("4th-letter").innerHTML = userInput; } else { document.getElementById("incorrect-letters").innerHTML = userInput; } } else { alert("Code is working"); } };

Solution

  • This:

    document.getElementById("incorrect-letters").innerHTML = userInput;
    

    should be this:

    document.getElementById("incorrect-letters").innerHTML =
       document.getElementById("incorrect-letters").innerHTML +userInput;
    

    So that you don't replace the element's innerHTML completely, but rather, you add to it.

    And, you should really set up cached references to the DOM elements that you'll be working with so that you don't have to re-scan the DOM every time the code runs. It also makes the code much simpler to read/write.

    And, you probably don't want to use key which will provide you with the actual key that the user pressed, rather than the character that that keypress produces. Instead you should use keyCode and code (keyCode is widely supported but is in the process of being replaced by code, which doesn't have widespread support yet).

    Also, consider taking the user's input and forcing it to lower case so that when you compare their guess against a letter, it's a case-insensitive guess.

    Additionally, ids cannot start with a number.

    Lastly, your if/`else' code works, but it can be streamlined as you'll see in my example below:

    // Wait until the DOM is fully loaded and then run the function
    window.addEventListener("DOMContentLoaded", function(){
    
        // Set up variable to cache reference to the DOM elements we'll be using
        var incorrectLetters = document.getElementById("incorrect-letters");
        var guesses = document.getElementById("guesses");
      
        // Find all the letter element containers:
        var containers = document.querySelectorAll(".letter");
        var foundCount = 0;
    
        // Set up the secret word
        var currentWord = "taco";
     
        document.onkeyup = function(event) {
       
          // event.keyCode and event.code return the numeric code for the character 
          // they produce. When passed to String.fromCharCode(), we get the actual
          // character that was produced by the key input, but this excludes keystrokes
          // that don't produce a visible character (space, backspace, tab, enter, etc.)
          // From there, we convert that character to lower-case.
          var userInput = String.fromCharCode(event.keyCode || event.code).toLowerCase();
          var found = false;
    
          // Check input to see if it is in the secret word array and, if so,
          // print the input in the correct position
          
          // Loop through each letter in the array
          for(var i = 0; i < currentWord.length; ++i){
            
            // Check the input against the current letter we're looping over
            if(userInput === currentWord[i]){
              
              // We have a match, put the letter in the container that is in the same
              // position in the array as it is in the word
              containers[i].textContent = userInput;
              
              // Flag that we have a matched letter and up the matched letter count
              found = true;
              foundCount++;
            }
          }
          
          // If all letters have been found, change display to show a winner
          if(foundCount === containers.length){
             guesses.classList.add("winner");
          }
          
          // If the input wasn't found after looping, write it in the bad guesses area
          if(!found) { incorrectLetters.innerHTML = incorrectLetters.innerHTML + userInput; }
    
        };
      
    });
    #incorrect-letters { 
      border:2px dashed blue; 
      background-color:rgba(100,200,100,.75); 
      height:1.5em; 
      font-family:monospaced;
      letter-spacing:.75em;
      font-weight:bold;
      line-height:1.5em;
      font-size:1.5em;
      padding:0 10px;
    }
    
    .letter { 
      float:left; 
      border-bottom:2px solid black;
      font-size:2em;
      color:green;
      width:2em;
      height:1em;
      margin-right:1em;
      text-align:center;
    }
    
    .winner {
      background-color:yellow;
      border:5px solid green;
      height:2.5em;
    }
    <p>Click on the document and type your letter guess</p>
    <p>Bad guesses:</p>
    <div id="incorrect-letters"></div>
    
    <p>Correct guesses:</p>
    <div id="guesses">
      <div class="letter" id="firstLetter"></div>
      <div class="letter" id="secondLetter"></div>
      <div class="letter" id="thirdLletter"></div>
      <div class="letter" id="fourthLetter"></div>
    </div>